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加密的编码公钥?