在javascript中使用RSA加密一个小字符串,然后在服务器上的java中解密

我想使用带有公钥的RSA在javascript中加密一个小字符串,然后使用私钥在java服务器端代码中解密该字符串。

我在javascript中使用此代码: http : //www-cs-students.stanford.edu/~tjw/jsbn/示例: http : //www-cs-students.stanford.edu/~tjw/jsbn/rsa2 html的

这个代码在java方面: 加密javascript中的字符串和java中的解密

这两个代码都可以独立工作,但它们彼此不了解。 今天需要解决这个问题,或者我愿意接受任何其他以这种方式工作的非对称算法。

您正在使用Java端的原始加密和使用Java Card端的PKCS#1 v1.5填充的RSA加密。 您应该尝试通过javax.crypto.Cipher.getInstance("RSA/None/PKCS1Padding")使用Java RSA。 如果存在,请不要忘记删除任何base 64编码。

想离开这个例子继续下一代:)

首先,我们需要在java代码中生成密钥对

 KeyPairGenerator kpg; try { kpg = KeyPairGenerator.getInstance("RSA"); kpg.initialize(2048); KeyPair kp = kpg.genKeyPair(); yourVariablePublic = kp.getPublic(); yourVariablePublic = kp.getPrivate(); } catch(NoSuchAlgorithmException e) { } 

现在让我们转到我们当前页面的java代码:

 // receiving public key from where you store it Key publicKey = YourCarrierClass.getYourVariablePublic(); KeyFactory fact; // initializing public key variable RSAPublicKeySpec pub = new RSAPublicKeySpec(BigInteger.ZERO, BigInteger.ZERO); try { fact = KeyFactory.getInstance("RSA"); pub = fact.getKeySpec(publicKey, RSAPublicKeySpec.class); } catch(NoSuchAlgorithmException e1) { } catch(InvalidKeySpecException e) { } // now you should pass Modulus string onto your html(jsp) in such way String htmlUsedModulus = pub.getModulus().toString(16); // send somehow this String to page, so javascript can use it 

现在为javascript方面:

 function sendPassword() { var password = $('#passwordField').val(); var rsa = new RSAKey(); rsa.setPublic($('#keyModulus').text(), '10001'); var res = rsa.encrypt(password); $('#ajaxSentPassword').val(res); } 

并在java代码中解密它:

  Key privateKey = YourCarrierClass.getYourVariablePrivate(); Cipher cipher; BigInteger passwordInt = new BigInteger(ajaxSentPassword, 16); byte[] dectyptedText = new byte[1]; try { cipher = javax.crypto.Cipher.getInstance("RSA/ECB/PKCS1Padding"); byte[] passwordBytes = passwordInt.toByteArray(); cipher.init(Cipher.DECRYPT_MODE, privateKey); dectyptedText = cipher.doFinal(passwordBytes); } catch(NoSuchAlgorithmException e) { } catch(NoSuchPaddingException e) { } catch(InvalidKeyException e) { } catch(IllegalBlockSizeException e) { } catch(BadPaddingException e) { } String passwordNew = new String(dectyptedText); System.out.println("Password new " + passwordNew); 

你走了,对不起,我不善于处理这些捕获条款。

================================================== ==================

Upd:在这里,我发现了一些有关此代码的问题。 首先,你可以改变算法

 javax.crypto.Cipher.getInstance("RSA/ECB/PKCS1Padding"); 

至:

 javax.crypto.Cipher.getInstance("RSA"); 

但这并不重要,它适用于两者。 现在真正的问题是这条线

 byte[] passwordBytes = passwordInt.toByteArray(); 

这里当你从BigInteger生成字节数组时,它有时会在前面添加[0]作为signum(有时不是!所以算法可以解密那个数组),所以字节数组大小可以是65/129/257,这不能被算法解密,它抛出IllegalBlockSizeException。 在模数RSA密钥中获取1字节额外时讨论了这个问题,有时对指数也有疑问。 最简单的解决方案是从数组中丢弃零:

  byte[] byteArray = new byte[256]; BigInteger passwordInt = new BigInteger(password, 16); if (passwordInt.toByteArray().length > 256) { for (int i=1; i<257; i++) { byteArray[i-1] = passwordInt.toByteArray()[i]; } } else { byteArray = passwordInt.toByteArray(); }