1. 背景
- 对接第三方系统,数据需要加密传输,但是双方系统使用的开发语言不同,所以要根据实际情况调整加解密方法中的具体细节
2. go
- gcm 无填充
- 初始化向量iv是固定的,偏移量为0,而且要转成16进制字节数组
- 加密后将字节数组转成16进制字符串,不是base64
package main
import (
"crypto/aes"
"crypto/cipher"
"encoding/hex"
"fmt"
)
func GCMEncrypt(data, key, iv string) string {
secretKey := []byte(key)
plaintext := []byte(data)
block, err := aes.NewCipher(secretKey)
if err != nil {
panic(err.Error())
}
nonce, _ := hex.DecodeString(iv)
aesGcm, err := cipher.NewGCM(block)
if err != nil {
panic(err.Error())
}
ciphertext := aesGcm.Seal(nil, nonce, plaintext, nil)
return fmt.Sprintf("%x", ciphertext)
}
func GCMDecrypt(data, key, iv string) string {
secretKey := []byte(key)
ciphertext, _ := hex.DecodeString(data)
nonce, _ := hex.DecodeString(iv)
block, err := aes.NewCipher(secretKey)
if err != nil {
panic(err.Error())
}
aesGcm, err := cipher.NewGCM(block)
if err != nil {
panic(err.Error())
}
plaintext, err := aesGcm.Open(nil, nonce, ciphertext, nil)
if err != nil {
panic(err.Error())
}
return string(plaintext)
}
func main() {
iv := "2ea2fb4267fd4ef5b5b7cc70"
key := "APP256Key-32bfeeb11965824f3ba145"
encrypt := GCMEncrypt("1234567890", key, iv)
fmt.Println(encrypt)
decrypt := GCMDecrypt(encrypt, key, iv)
fmt.Println(decrypt)
}
11c40009985dbe47d1eda157068794a9796bc47b9fe9dc913dbb
1234567890
3. java
- BouncyCastle是一个提供了很多哈希算法和加密算法的第三方库。它提供了很多Java标准库没有提供的哈希算法和加密算法。
- 引入bouncycastle
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class AesUtil2 {
private static final String MODE = "AES/GCM/NoPadding";
static {
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
Security.addProvider(new BouncyCastleProvider());
}
}
public static String encryptWithIV(String data, String key, String iv) throws Exception {
Cipher cipher = Cipher.getInstance(MODE);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES"),
new IvParameterSpec(hexToBytes(iv)));
return bytesToHex(cipher.doFinal(data.getBytes(StandardCharsets.UTF_8)));
}
public static String decryptWithIV(String data, String key, String iv) throws Exception {
Cipher cipher = Cipher.getInstance(MODE);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES"),
new IvParameterSpec(hexToBytes(iv)));
return new String(cipher.doFinal(hexToBytes(data)));
}
public static byte[] hexToBytes(String data) {
byte[] byteArray = new BigInteger(data, 16).toByteArray();
if (byteArray[0] == 0) {
byte[] output = new byte[byteArray.length - 1];
System.arraycopy(byteArray, 1, output, 0, output.length);
return output;
}
return byteArray;
}
public static String bytesToHex(byte[] data) {
return new BigInteger(1, data).toString(16);
}
public static void main(String[] args) {
String keys = "APP256Key-32bfeeb11965824f3ba145";
String ivs = "2ea2fb4267fd4ef5b5b7cc70";
String data = "1234567890";
String s = encryptWithIV(data, keys, ivs);
System.out.println(s);
System.out.println(decryptWithIV(s, keys, ivs));
}
}
11c40009985dbe47d1eda157068794a9796bc47b9fe9dc913dbb
1234567890