前端jsencrypt加密,后端无法解密

前后端RSA加密

在做一个web安全登录的作业时,遇到前后端RSA加密问题。。

  1. 后端 java
    生成RSA密钥对,privateKey,publicKey
    后端RSA是从帖子上抄的:
    (学习加密四spring boot 使用RSA+AES混合加密,前后端传递参数加解密)[https://blog.csdn.net/baidu_38990811/article/details/83540404]

    **使用PKCS8规范**
    
// 后端部分代码 RSA
    /**
     * 生成密钥对(公钥和私钥)
     * @return
     * @throws Exception
     */
    public static Map<String, Object> genKeyPair() throws Exception {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        keyPairGen.initialize(INITIALIZE_LENGTH);
        KeyPair keyPair = keyPairGen.generateKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        Map<String, Object> keyMap = new HashMap<String, Object>(2);
        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
        return keyMap;
    }

        /**
     * 私钥解密
     * @param encryptedData  已加密数据
     * @param privateKey 私钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception {
        byte[] keyBytes = Base64.decodeBase64(privateKey);

        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

        cipher.init(Cipher.DECRYPT_MODE, privateK);
        int inputLen = encryptedData.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段解密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_DECRYPT_BLOCK;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        return decryptedData;
    }

  1. 前端:vue+webpack

    • 从后端获取一个公钥**publicKey**
      • 使用jsencrypt 和 publicKey加密内容,得到String encrypted
  2. 后端拿到传回的encrypted, 再解密时报错

javax.crypto.BadPaddingException: Decryption error
    at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:383)
    at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:294)
    at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:363)
    at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
    at javax.crypto.Cipher.doFinal(Cipher.java:2222)
    at com.security.loginserver.Util.RSAUtils.decryptByPrivateKey(RSAUtils.java:126)
    at com.security.loginserver.Util.RSAUtils.decryptDataOnJava(RSAUtils.java:285)

测试情况

  1. 后端单独测试RSA加密解密,正常
  2. 前端单独测试RSA加密解密,使用后端的publicKey和privatekey正常
  3. 搜到的贴子说,原因是JSEncrypt使用pkcs1规范,后端java用了**PKCS8规范**,,,然后就无从下手了
  4. 求助大佬

现象:同样的内容使用jsencrypt加密和后端RSA加密后,密文结构类似长度不一样
结果:jsencrypt加密后解密正常,后端RSA加密解密正常(后端直接使用的hutool),jsencrypt加密后的密文给后端解密失败了
解决办法:求解

有结果了吗?遇到同样问题,求解。

试一下这个:
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] cipherText = cipher.doFinal(Base64.decodeBase64(encrypted.getBytes()));
String decrypted = new String(cipherText, "UTF-8");
System.out.println("解密后内容:" + decrypted);

privateKey 是后台生成的私钥
encrypted 是利用jsencrypt加密后的密文