使用加密库看起来密码更新没有按预期工作?

问题描述 投票:0回答:1

当传递的字符串不是 16 字节时,我有加密模块进行字符串加密,我假设 cipher.update() 应该做一些填充并创建 16 字节字符串,但在调试 cipher.update 返回空字符串时不会发生这种情况,还有其他方法吗使用加密进行填充。

index.js

function paymentIdencryption(text)

        const secret_key = "EiE0BVQle0xFjZvYOupKjFGHAcAwBaTjlZ7G7rryNos=";
        const secretKeyWordArray = CCrypto.enc.Utf8.parse(secret_key);

        const cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(secret_key, 'base64'), iv);
        let encrypted = cipher.update(JSON.stringify(text), 'utf8', 'base64');
        encrypted += cipher.final('base64');
        const encryptedData = { iv: iv.toString('base64'), encrypted: encodeURIComponent(encrypted)};
       return encryptedData.encrypted;
}

console.log(paymentIdencryption("1384220_8089105");

预期结果密钥大小:

GwJPNUfPXZZsuc0iqOFhn%2BYhMJKxXBUGl9g3iKqL8CE%3D

但它返回:jJtKhwjqS5N4ABIrZev8Ng%3D%3D

解密的Java代码

var imp = new JavaImporter(com.vordel.mime,org.json.simple.JSONObject,com.vordel.trace);
 
with(imp) {
function invoke(msg)         {            
 
var encodedKey = "${env.SPL.paymentMethodId.key}";
Trace.info ("env.SPL.paymentMethodId.key -- encodedKey  = " + encodedKey); 
var encodedPaymentInfo= msg.get("cvs.paymentMethodId");
 
var encryptedPaymentInfo = java.net.URLDecoder.decode(encodedPaymentInfo,"UTF-8");

var decodedKey = java.util.Base64.getDecoder().decode(encodedKey.getBytes("UTF-8"));
var decodedcipher = java.util.Base64.getDecoder().decode(encryptedPaymentInfo.getBytes("UTF-8"));

 
var cipher = javax.crypto.Cipher.getInstance("AES/CBC/PKCS5Padding"); 
var secretKey = new javax.crypto.spec.SecretKeySpec(decodedKey, "AES"); 
var iv = new javax.crypto.spec.IvParameterSpec(decodedcipher,0,16);
cipher.init(javax.crypto.Cipher.DECRYPT_MODE,secretKey,iv);
 
var decryptedPaymentInfo = cipher.doFinal(decodedcipher, 16, decodedcipher.length-16);
var paymentInfo = new java.lang.String(decryptedPaymentInfo,"UTF-8"); 
var patientId = paymentInfo.substring(paymentInfo.indexOf("_")+1, paymentInfo.length());
var paymentId = paymentInfo.substring(0, paymentInfo.indexOf("_"));
 
msg.put("cvs.spl.patientId",patientId);
msg.put("cvs.spl.paymentId",paymentId);
 
return true;         
 
}
};
javascript java node.js encryption cryptojs
1个回答
0
投票

Java 代码对加密数据执行 URL 解码,然后进行 Base64 解码。结果的前 16 个字节用作 IV,其余的用作密文。
密钥是 Base64 解码的。
有了密钥和 IV,密文现在可以使用 CBC 模式下的 AES 和 PKCS#7 填充进行解密。
解密后的数据是用UTF-8解码的。
从结果字符串中提取

patientid
_
之后的数据)和
paymentid
_
之前的数据)。

由此可以确定加密的逻辑:

  • 密钥的Base64解码
  • 生成随机 16 字节 IV
  • 使用密钥和 IV 进行 aes-256-cbc 加密(AES-256,因为有 32 字节密钥)
  • IV 和密文的串联
  • 密文的Base64编码以及后续的URL编码

可能的 NodeJS 代码:

var crypto = require('crypto')
function paymentIdencryption(text) {
    const secret_key = "EiE0BVQle0xFjZvYOupKjFGHAcAwBaTjlZ7G7rryNos=";
    const iv = crypto.randomBytes(16);
    const cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(secret_key, 'base64'), iv);
    const encrypted = Buffer.concat([iv, cipher.update(text, 'utf8'), cipher.final()]);
    return encodeURIComponent(encrypted.toString('base64'))
}
console.log(paymentIdencryption("1384220_8089105"));

可能的输出(由于随机 IV,每次加密都会发生变化):

5I43wWYs84XQk9Pe0IMl4g%2B7s%2BgwcJrPsWo9gcX25y8%3D 

用Java代码测试:

public class Main {
    public static void main(String[] args) throws Exception {
        
        var encodedPaymentInfo = "5I43wWYs84XQk9Pe0IMl4g%2B7s%2BgwcJrPsWo9gcX25y8%3D"; 
        var encodedKey = "EiE0BVQle0xFjZvYOupKjFGHAcAwBaTjlZ7G7rryNos=";
        
        var encryptedPaymentInfo = java.net.URLDecoder.decode(encodedPaymentInfo,"UTF-8");

        var decodedKey = java.util.Base64.getDecoder().decode(encodedKey.getBytes("UTF-8"));
        var decodedcipher = java.util.Base64.getDecoder().decode(encryptedPaymentInfo.getBytes("UTF-8"));
         
        var cipher = javax.crypto.Cipher.getInstance("AES/CBC/PKCS5Padding"); 
        var secretKey = new javax.crypto.spec.SecretKeySpec(decodedKey, "AES"); 
        var iv = new javax.crypto.spec.IvParameterSpec(decodedcipher,0,16);
        cipher.init(javax.crypto.Cipher.DECRYPT_MODE,secretKey,iv);
         
        var decryptedPaymentInfo = cipher.doFinal(decodedcipher, 16, decodedcipher.length-16);
        var paymentInfo = new java.lang.String(decryptedPaymentInfo,"UTF-8"); 
        var patientId = paymentInfo.substring(paymentInfo.indexOf("_")+1, paymentInfo.length());
        var paymentId = paymentInfo.substring(0, paymentInfo.indexOf("_"));
         
        System.out.println("cvs.spl.patientId: " + patientId);
        System.out.println("cvs.spl.paymentId: " + paymentId);
    }
}

输出:

cvs.spl.patientId: 8089105
cvs.spl.paymentId: 1384220

等于原始纯文本的数据。

© www.soinside.com 2019 - 2024. All rights reserved.