RSA加密Javascript和Decrypt Java
用不同的组合花了差不多2天。我在java中使用RSA算法生成一个非对称密钥对(公共和私有),并试图在javascript中使用公钥来加密一些文本并在服务器端的java中解密。 尝试解密在javascript中加密的字符串时,我收到“javax.crypto.IllegalBlockSizeException:数据不能超过128个字节”exception。 会感激一些帮助……
使用这个Javascript库加密。
https://github.com/wwwtyro/cryptico
var publicKeyString =“”//在java中生成的base64encoded公钥字符串
这是我的javascript代码
var EncryptionResult = cryptico.encrypt("somestring", publicKeyString); console.log("Encrypted status-"+EncryptionResult.status); console.log("Encrypted String-"+EncryptionResult.cipher);
它成功加密了字符串。
Java密钥生成和解密
Cipher cipher = Cipher.getInstance("RSA"); KeyFactory fact = KeyFactory.getInstance("RSA"); KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(1024); // 1024 used for normal KeyPair keyPair = keyPairGenerator.generateKeyPair(); PublicKey publicKey = keyPair.getPublic(); PrivateKey privateKey = keyPair.getPrivate(); FileOutputStream fos = null; ObjectOutputStream oos = null;
用于将私钥存储在用于在解密方法中解密的文件的代码。
RSAPrivateKeySpec rsaPrivKeySpec = fact.getKeySpec(privateKey, RSAPrivateKeySpec.class); System.out.println("Writing private key..."); fos = new FileOutputStream(PRIVATE_KEY_FILE); oos = new ObjectOutputStream(new BufferedOutputStream(fos)); oos = new ObjectOutputStream(new BufferedOutputStream(fos)); oos.writeObject(rsaPrivKeySpec.getModulus()); oos.writeObject(rsaPrivKeySpec.getPrivateExponent()); oos.close();
解密方法
public String decrypt(String ciphertext) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException { if (ciphertext.length() == 0) return null; byte[] dec = org.apache.commons.codec.binary.Base64.decodeBase64(ciphertext); try { System.out.println("Private Key file name----"+PRIVATE_KEY_FILE); privateKey = readPrivateKeyFromFile(PRIVATE_KEY_FILE); } catch (IOException e) { e.printStackTrace(); } cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] decrypted = cipher.doFinal(dec); return new String(decrypted, PLAIN_TEXT_ENCODING); } //reading private key from file public PrivateKey readPrivateKeyFromFile(String fileName) throws IOException { FileInputStream fis = null; ObjectInputStream ois = null; try { fis = new FileInputStream(new File(fileName)); ois = new ObjectInputStream(fis); System.out.println("Private Key file-"+fileName); BigInteger modulus = (BigInteger) ois.readObject(); BigInteger exponent = (BigInteger) ois.readObject(); // Get Private Key RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec(modulus, exponent); KeyFactory fact = KeyFactory.getInstance("RSA"); PrivateKey privateKey = fact.generatePrivate(rsaPrivateKeySpec); return privateKey; } catch (Exception e) { e.printStackTrace(); } finally { if (ois != null) { ois.close(); if (fis != null) { fis.close(); } } } return null; }
从Cryptico
文档来看,它似乎不是一个简单的RSA加密,而是一个生成AES密钥的复杂操作,使用RSA对其进行加密,使用AES加密数据并输出加密的AES密钥和加密数据的串联。 如果你想在Java中解密它,你将不得不检查Cryptico
源代码并在Java中重新实现它。
至于你当前的尝试和javax.crypto.IllegalBlockSizeException: Data must not be longer than 128 bytes
错误:
如果未指定完整转换,则RSA的默认JCE转换为RSA / ECB / PKCS1Padding 。
在此模式下,RSA加密或解密长度不大于密钥大小的单个数据块(更具体地说,如果输入的字节序列被解释为大整数,则其值应小于模数由RSA使用)。 您可以在此问题和此问题中找到更多信息。
密钥大小为1024位,最大数据大小为128字节,这正是exception所说的,因为Cryptico
的输出显然不是单个RSA块,其长度大于“普通”RSA所期望的长度。 尝试在Java中使用其他一些密码模式或填充模式也无济于事。
感谢Oleg的详细信息。 我一定会看看它。
现在我切换到jsencrypt,似乎工作正常。
https://github.com/travist/jsencrypt
编辑
如何获取js加密的编码公钥?