Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在node js中使用AES/GCM/NoPadding算法使用密钥和iv加密有效负载,并在java中解密_Java_Node.js_Encryption_Cryptography_Aes Gcm - Fatal编程技术网

在node js中使用AES/GCM/NoPadding算法使用密钥和iv加密有效负载,并在java中解密

在node js中使用AES/GCM/NoPadding算法使用密钥和iv加密有效负载,并在java中解密,java,node.js,encryption,cryptography,aes-gcm,Java,Node.js,Encryption,Cryptography,Aes Gcm,我已经使用node.js对文件进行了加密,并使用JAVA进行了解密。解密是在JAVA中使用“AES/GCM/Nopadding”算法完成的,它是第三方应用程序,因此我看不到JAVA代码。 我正在使用“aes-128-gcm”算法加密node.js中的有效负载。 为此,我尝试模仿一个工作的java加密代码 我尝试过加密和节点伪造。 iam正在获取输出,但在提交负载时收到错误“加密错误-负载未正确加密” 请帮我找出我在这段代码中做错了什么 java中的工作代码 public void encrypt

我已经使用node.js对文件进行了加密,并使用JAVA进行了解密。解密是在JAVA中使用“AES/GCM/Nopadding”算法完成的,它是第三方应用程序,因此我看不到JAVA代码。 我正在使用“aes-128-gcm”算法加密node.js中的有效负载。 为此,我尝试模仿一个工作的java加密代码

我尝试过加密和节点伪造。
iam正在获取输出,但在提交负载时收到错误“加密错误-负载未正确加密”

请帮我找出我在这段代码中做错了什么

java中的工作代码

public void encrypt(@NonNull final byte[] payload, @NonNull final byte[] key) throws GeneralSecurityException
{
    SecretKeySpec codingKey = new SecretKeySpec(key, AES);
    Cipher cipher = AEC_GCM_THREAD_CIPHER.get();
    byte[] iv = new byte[cipher.getBlockSize()];
    RANDOM.nextBytes(iv);

    cipher.init(Cipher.ENCRYPT_MODE, codingKey, new IvParameterSpec(iv));
    final byte[] encryptedPayload = cipher.doFinal(payload);
    byte[] encryptMerchantKey = encryptMerchantKey(key);

    String payloadFinal = encodeToUrlString(encryptedPayload);    // final payload
    String ivFinal =  encodeToUrlString(iv);                  // final iv
    String keyFinal =  encodeToUrlString(encryptMerchantKey);  // final key

    System.out.println("Payload");
    System.out.println(payloadFinal);
    System.out.println("iv");
    System.out.println(ivFinal);
    System.out.println("key");
    System.out.println(keyFinal);
}
代码iam已在节点js中尝试

function encrypt(payload) {

    let key = forge.random.getBytesSync(16);
    let iv = forge.random.getBytesSync(16);

    let cipher = forge.cipher.createCipher("AES-GCM", key);
    cipher.start({ iv: iv});
    cipher.update(forge.util.createBuffer(payload));
    cipher.finish();

    let encrypted = forge.util.encode64(cipher.output.getBytes());
    let tag = forge.util.encode64(cipher.mode.tag.getBytes());
    let iv64 = forge.util.encode64(iv);

    let encryptedPayload = encrypted+tag;

    //RSA Encryption
    encryptedkey = RSAencrypt(forge.util.encode64(key));

     return {
     "payload" : base64url.fromBase64(encryptedPayload) ,
     "iv" : base64url.fromBase64(iv64).length,
     "key" : base64url.fromBase64(encryptedkey)
     };
}
Rsa描述可以很好地解密密钥。
aes加密存在一些问题。正如代码所示,我将auth标记和加密数据添加在一起,但没有任何用处。

问题在于forge缓冲区需要转换为节点缓冲区 此代码现在正在运行。谢谢,@Maarten Bodewes的建议

function encrypt(payload) {

    //initialize forge random buffer
    var key = forge.random.getBytesSync(16);
    var iv = forge.random.getBytesSync(16);

    let cipher = forge.cipher.createCipher("AES-GCM", key);
    cipher.start({iv : iv});
    cipher.update(forge.util.createBuffer(payload));
    cipher.finish();

    let encrypted = cipher.output.data;
    let tag = cipher.mode.tag.data;
    let encryptedLoad = encrypted+tag;

    // node buffer and forge buffer differ, so the forge buffer must be converted to node Buffer            
    iv = Buffer.from(iv, "binary");
    encryptedLoad = Buffer.from(encryptedLoad, "binary");

    //Calling RSA Encryption
    encryptedKey = RSAencrypt(key);

    return {
     "payload" : base64url(encryptedLoad) ,
     "iv" : base64url(iv),
     "key" : base64url.fromBase64(encryptedKey)
     };
}

我有一个完整的angular和java加密和解密示例,您可以按照这个示例进行更改。
使用命令“npm Install node forge”安装node forge

我使用CryptoJS生成随机字符串,因为随机节点forge会给出不可传递的字符串

解密此trasmitsg的java代码是

public String getDecrypt(String transmsg) throws Exception {
    String keyString = transmsg.substring(0, 16);
    String ivString = transmsg.substring(16, 32);
    String additionalString = transmsg.substring(32, 56);
    String cipherString = transmsg.substring(56);

    byte[] keyBytes = keyString.getBytes();
    SecretKey key = new SecretKeySpec(keyBytes, "AES");
    byte[] ivBytes = ivString.getBytes();

    byte[] one = Base64.getDecoder().decode(cipherString);
    byte[] two = Base64.getDecoder().decode(additionalString);
    byte[] cipherText = ArrayUtils.addAll(one, two);
    return decrypt(cipherText, key, ivBytes);
}

public static String decrypt(byte[] cipherText, SecretKey key, byte[] IV) throws Exception {
    // Get Cipher Instance
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

    // Create SecretKeySpec
    SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");

    // Create GCMParameterSpec
    GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH , IV);

    // Initialize Cipher for DECRYPT_MODE
    cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);

    cipher.updateAAD("nvn".getBytes());
    byte[] decryptedText = cipher.doFinal(cipherText);

    return new String(decryptedText);
}

干杯

toeknToUrlString
做什么?为什么转换为base 64只是为了在NodeJS代码中再次解码?请注意,GCM的nonce(IV)的默认大小为12字节,而不是16字节,因此与块大小不同(但16字节的nonce仍然应该兼容)。请要求接受方提供规格说明,不要让自己猜测!您还应该发布输出,不要让我们自己生成输出。您的Java显然添加了输出语句,那么它在哪里?为什么您的NodeJ没有相同类型的调试语句?提交负载时“加密错误-负载未正确加密”。这不是函数的输出,这是您提交负载的一方的结果(由于我们甚至不知道您是如何提交数据的,我们甚至无法判断该错误是否是在您向我们展示的函数中产生的)。由于您对(学习)没有表现出丝毫的兴趣如何调试您自己的代码,例如,将函数的输出相互比较,我认为我们在这里无法帮助您。这不是一个最小的完整且可验证的示例,因为它不完整,缺少输入/输出以及输入和输出的要求。您没有将pass参数用于加密oO-是吗碰巧js中也有解密功能?@jonathanHeindl你弄明白了吗?他在发送数据时没有使用pass或“key”。有人能确认吗?pass是进入key的东西在我的情况下,我必须做一些散列来获得真正的key:var key=forge.pkcs5.pbkdf2(secret,salt,65536,32,'sha256'));您可以分享java部分来解码它吗?
public String getDecrypt(String transmsg) throws Exception {
    String keyString = transmsg.substring(0, 16);
    String ivString = transmsg.substring(16, 32);
    String additionalString = transmsg.substring(32, 56);
    String cipherString = transmsg.substring(56);

    byte[] keyBytes = keyString.getBytes();
    SecretKey key = new SecretKeySpec(keyBytes, "AES");
    byte[] ivBytes = ivString.getBytes();

    byte[] one = Base64.getDecoder().decode(cipherString);
    byte[] two = Base64.getDecoder().decode(additionalString);
    byte[] cipherText = ArrayUtils.addAll(one, two);
    return decrypt(cipherText, key, ivBytes);
}

public static String decrypt(byte[] cipherText, SecretKey key, byte[] IV) throws Exception {
    // Get Cipher Instance
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

    // Create SecretKeySpec
    SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");

    // Create GCMParameterSpec
    GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH , IV);

    // Initialize Cipher for DECRYPT_MODE
    cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);

    cipher.updateAAD("nvn".getBytes());
    byte[] decryptedText = cipher.doFinal(cipherText);

    return new String(decryptedText);
}