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

Encrypt a small string with RSA in javascript then decrypt in java on server

本文关键字:字符串 然后 服务器 解密 java 一个 javascript RSA 加密      更新时间:2023-09-26

我想使用 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);

给你,对不起,我不擅长处理这些捕获条款。

====

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

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

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

自:

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

但这不是必需的,它适用于两者。现在真正的问题是关于这条线

byte[] passwordBytes = passwordInt.toByteArray();

这里当你从 BigInteger 生成字节数组时,它有时会在前面添加 [0] 作为符号(有时不是!所以算法可以破译该数组),所以字节数组大小可以是 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();
    }
相关文章: