在Java和golang中使用AES时获得不同的结果(cyphertext)
我试图将AES加密的java代码复制到Golang中。 然而,我在golang没有得到相同的输出 我尝试了以下代码: Java代码:在Java和golang中使用AES时获得不同的结果(cyphertext),java,go,aes,encryption-symmetric,Java,Go,Aes,Encryption Symmetric,我试图将AES加密的java代码复制到Golang中。 然而,我在golang没有得到相同的输出 我尝试了以下代码: Java代码: package EncryptionTest; import java.security.Key; import java.util.Base64; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; public class EncryptionDecryptionAES
package EncryptionTest;
import java.security.Key;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class EncryptionDecryptionAES {
static Cipher cipher;
public static void main(String[] args) throws Exception {
Key secretKey;
secretKey = (Key)new SecretKeySpec("0123456789012345".getBytes(), "AES");
cipher = Cipher.getInstance("AES");
String plainText = "AES Symmetric Encryption Decryption";
System.out.println("Plain Text Before Encryption: " + plainText);
String encryptedText = encrypt(plainText, secretKey);
System.out.println("Encrypted Text After Encryption: " + encryptedText);
String decryptedText = decrypt(encryptedText, secretKey);
System.out.println("Decrypted Text After Decryption: " + decryptedText);
}
public static String encrypt(String plainText, Key secretKey) throws Exception {
byte[] plainTextByte = plainText.getBytes();
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedByte = cipher.doFinal(plainTextByte);
Base64.Encoder encoder = Base64.getEncoder();
String encryptedText = encoder.encodeToString(encryptedByte);
return encryptedText;
}
public static String decrypt(String encryptedText, Key secretKey) throws Exception {
Base64.Decoder decoder = Base64.getDecoder();
byte[] encryptedTextByte = decoder.decode(encryptedText);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedByte = cipher.doFinal(encryptedTextByte);
String decryptedText = new String(decryptedByte);
return decryptedText;
}
}
package main
import (
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"fmt"
)
const NONCESIZE = 12
func main() {
key := []byte("0123456789012345")
plaintext := []byte("AES Symmetric Encryption Decryption")
block, err := aes.NewCipher(key)
if err != nil {
panic(err.Error())
}
nonce := make([]byte, NONCESIZE)
aesgcm, err := cipher.NewGCM(block)
if err != nil {
panic(err.Error())
}
ciphertext := aesgcm.Seal(nil, nonce, plaintext, nil)
fmt.Println("Encrypted Text is : ", base64.StdEncoding.EncodeToString(ciphertext))
}
Java代码输出:
加密前的纯文本:AES对称加密解密
加密后的加密文本:vSmrgH3qU+qEq+3ui0YvwCa6PDBcMyhgOlbh3+zzM+cON6feLk2u1iPW7lITD3vn
解密后解密的文本:AES对称加密解密
戈朗代码:
package EncryptionTest;
import java.security.Key;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class EncryptionDecryptionAES {
static Cipher cipher;
public static void main(String[] args) throws Exception {
Key secretKey;
secretKey = (Key)new SecretKeySpec("0123456789012345".getBytes(), "AES");
cipher = Cipher.getInstance("AES");
String plainText = "AES Symmetric Encryption Decryption";
System.out.println("Plain Text Before Encryption: " + plainText);
String encryptedText = encrypt(plainText, secretKey);
System.out.println("Encrypted Text After Encryption: " + encryptedText);
String decryptedText = decrypt(encryptedText, secretKey);
System.out.println("Decrypted Text After Decryption: " + decryptedText);
}
public static String encrypt(String plainText, Key secretKey) throws Exception {
byte[] plainTextByte = plainText.getBytes();
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedByte = cipher.doFinal(plainTextByte);
Base64.Encoder encoder = Base64.getEncoder();
String encryptedText = encoder.encodeToString(encryptedByte);
return encryptedText;
}
public static String decrypt(String encryptedText, Key secretKey) throws Exception {
Base64.Decoder decoder = Base64.getDecoder();
byte[] encryptedTextByte = decoder.decode(encryptedText);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedByte = cipher.doFinal(encryptedTextByte);
String decryptedText = new String(decryptedByte);
return decryptedText;
}
}
package main
import (
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"fmt"
)
const NONCESIZE = 12
func main() {
key := []byte("0123456789012345")
plaintext := []byte("AES Symmetric Encryption Decryption")
block, err := aes.NewCipher(key)
if err != nil {
panic(err.Error())
}
nonce := make([]byte, NONCESIZE)
aesgcm, err := cipher.NewGCM(block)
if err != nil {
panic(err.Error())
}
ciphertext := aesgcm.Seal(nil, nonce, plaintext, nil)
fmt.Println("Encrypted Text is : ", base64.StdEncoding.EncodeToString(ciphertext))
}
Golang代码输出:
加密文本是:7UMh49c5Wqb2BzlttKBEnq5g4fxMK9oJs1EUDIgWzVwlY28k+qd/OFG9SJCKBASX6DHP在go代码中,您在GCM模式下使用AES,12字节的零作为IV,但在java代码中,您使用的默认AES模式在不同的java版本中不同 通过使用GCM模式(在BouncyCastle中提供)并设置相同的IV(12字节零),我得到了相同的输出:
package EncryptionTest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.Key;
import java.security.Security;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class EncryptionDecryptionAES {
static Cipher cipher;
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
Key secretKey;
secretKey = (Key)new SecretKeySpec("0123456789012345".getBytes(), "AES");
cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");
String plainText = "AES Symmetric Encryption Decryption";
System.out.println("Plain Text Before Encryption: " + plainText);
String encryptedText = encrypt(plainText, secretKey);
System.out.println("Encrypted Text After Encryption: " + encryptedText);
String decryptedText = decrypt(encryptedText, secretKey);
System.out.println("Decrypted Text After Decryption: " + decryptedText);
}
public static String encrypt(String plainText, Key secretKey) throws Exception {
byte[] plainTextByte = plainText.getBytes();
byte[] iv = new byte[12];
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
byte[] encryptedByte = cipher.doFinal(plainTextByte);
Base64.Encoder encoder = Base64.getEncoder();
String encryptedText = encoder.encodeToString(encryptedByte);
return encryptedText;
}
public static String decrypt(String encryptedText, Key secretKey) throws Exception {
Base64.Decoder decoder = Base64.getDecoder();
byte[] encryptedTextByte = decoder.decode(encryptedText);
byte[] iv = new byte[12];
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
byte[] decryptedByte = cipher.doFinal(encryptedTextByte);
String decryptedText = new String(decryptedByte);
return decryptedText;
}
}
输出:
Plain Text Before Encryption: AES Symmetric Encryption Decryption
Encrypted Text After Encryption: 7UMh49c5Wqb2BzlttKBEnq5g4fxMK9oJs1EUDIgWzVwlY28k+qd/oFG9SJckBsaX6DHp
Decrypted Text After Decryption: AES Symmetric Encryption Decryption
在go代码中,您在GCM模式下使用AES,12字节的零作为IV,但在java代码中,您使用的是AES的默认模式,这在不同的java版本中是不同的 通过使用GCM模式(在BouncyCastle中提供)并设置相同的IV(12字节零),我得到了相同的输出:
package EncryptionTest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.Key;
import java.security.Security;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class EncryptionDecryptionAES {
static Cipher cipher;
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
Key secretKey;
secretKey = (Key)new SecretKeySpec("0123456789012345".getBytes(), "AES");
cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");
String plainText = "AES Symmetric Encryption Decryption";
System.out.println("Plain Text Before Encryption: " + plainText);
String encryptedText = encrypt(plainText, secretKey);
System.out.println("Encrypted Text After Encryption: " + encryptedText);
String decryptedText = decrypt(encryptedText, secretKey);
System.out.println("Decrypted Text After Decryption: " + decryptedText);
}
public static String encrypt(String plainText, Key secretKey) throws Exception {
byte[] plainTextByte = plainText.getBytes();
byte[] iv = new byte[12];
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
byte[] encryptedByte = cipher.doFinal(plainTextByte);
Base64.Encoder encoder = Base64.getEncoder();
String encryptedText = encoder.encodeToString(encryptedByte);
return encryptedText;
}
public static String decrypt(String encryptedText, Key secretKey) throws Exception {
Base64.Decoder decoder = Base64.getDecoder();
byte[] encryptedTextByte = decoder.decode(encryptedText);
byte[] iv = new byte[12];
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
byte[] decryptedByte = cipher.doFinal(encryptedTextByte);
String decryptedText = new String(decryptedByte);
return decryptedText;
}
}
输出:
Plain Text Before Encryption: AES Symmetric Encryption Decryption
Encrypted Text After Encryption: 7UMh49c5Wqb2BzlttKBEnq5g4fxMK9oJs1EUDIgWzVwlY28k+qd/oFG9SJckBsaX6DHp
Decrypted Text After Decryption: AES Symmetric Encryption Decryption
Java的getBytes不是确定性的,但取决于默认的字符集。AES使用随机初始向量进行加密。每次调用都会生成随机初始向量,这会导致不同的加密文本。@DogushanKAYA:我粘贴在这里的代码,生成相同的加密文本。Java的getBytes不确定,但取决于默认的字符集。AES使用随机初始向量进行加密。每次调用都会生成随机初始向量,这会导致不同的加密文本。@DogushanKAYA:我粘贴在这里的代码,生成相同的加密文本。这里我想知道我的java代码使用的默认模式是什么,以及如何在golang中复制相同的模式。@PrashantGupta依赖默认模式是有风险的。您应该显式地设置它。正如我所说,你可以在golang和java中使用GCM,但如果你不想使用bouncy castle,你可以在这两种语言中使用CBC模式。这里我想知道我的java代码使用的默认模式是什么,以及如何在golang中复制相同的模式。@PrashantGupta依赖默认模式是有风险的。您应该显式地设置它。正如我所说,您可以在golang和java中使用GCM,但如果您不想使用bouncy castle,您可以在这两种语言中使用CBC模式。