【问题标题】:Encrypt a small string with RSA in javascript then decrypt in java on server在 javascript 中使用 RSA 加密一个小字符串,然后在服务器上的 java 中解密
【发布时间】:2013-09-27 22:48:37
【问题描述】:

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

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

以及 java 端的这段代码: Encrypting string in javascript and decryption in java

两个代码独立运行良好,但彼此不理解。今天需要解决这个问题,否则我愿意接受任何其他以这种方式工作的非对称算法。

【问题讨论】:

  • “他们不理解彼此”——你能通过这两种算法来弄清楚它们为什么会出现分歧吗?仅仅是它们对结果的编码方式不同,或者一个假设一个固定的指数,或者一个不能处理另一个模数的大小,还是其他什么?
  • 请注意,仅仅从互联网上获取任何数据很少会导致系统安全。您不应该只信任任何代码并使用流行的、经过充分研究的库。

标签: java javascript encryption rsa jsbn


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    想把这个例子留给后代:)

    首先,我们需要在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);
    

    给你,抱歉,我不擅长处理这些 catch 子句。

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

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

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

    到:

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

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

    byte[] passwordBytes = passwordInt.toByteArray();
    

    这里当你从 BigInteger 生成字节数组时,它有时会在前面添加 [0] 作为符号(有时不是!所以算法可以破译那个数组),所以字节数组大小可以是 65/129/257,无法破译通过算法,它会抛出 IllegalBlockSizeException。这个问题在Getting 1 byte extra in the modulus RSA Key and sometimes for exponents also 问题中讨论。 最简单的解决方案就是从数组中扔掉那个零:

        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();
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-29
      • 2018-01-17
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      相关资源
      最近更新 更多