java 实现 gcm
时间: 2023-08-02 12:09:10 浏览: 231
GMM算法java实现
在Java中实现GCM加密可以使用Java Cryptography Extension (JCE)提供的javax.crypto.Cipher类,该类提供了GCM加密算法的实现。以下是一个简单的示例代码:
```java
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;
public class GcmExample {
private static final int TAG_LENGTH_BITS = 128;
private static final int IV_LENGTH_BYTES = 12;
private static final int KEY_LENGTH_BYTES = 16;
public static void main(String[] args) throws Exception {
// 示例数据
String keyStr = "000102030405060708090a0b0c0d0e0f";
String ivStr = "10111213141516";
String data = "Hello, world!";
byte[] key = hexToBytes(keyStr);
byte[] iv = hexToBytes(ivStr);
// 加密
byte[] encrypted = encrypt(data.getBytes(StandardCharsets.UTF_8), key, iv);
System.out.println("Cipher text: " + Base64.getEncoder().encodeToString(encrypted));
// 解密
byte[] decrypted = decrypt(encrypted, key, iv);
System.out.println("Decrypted data: " + new String(decrypted, StandardCharsets.UTF_8));
}
private static byte[] encrypt(byte[] data, byte[] key, byte[] iv) throws Exception {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
GCMParameterSpec gcmSpec = new GCMParameterSpec(TAG_LENGTH_BITS, iv);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmSpec);
byte[] encrypted = cipher.doFinal(data);
byte[] tag = cipher.getParameters().getParameterSpec(GCMParameterSpec.class).getIV();
byte[] result = new byte[encrypted.length + tag.length];
System.arraycopy(encrypted, 0, result, 0, encrypted.length);
System.arraycopy(tag, 0, result, encrypted.length, tag.length);
return result;
}
private static byte[] decrypt(byte[] data, byte[] key, byte[] iv) throws Exception {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
GCMParameterSpec gcmSpec = new GCMParameterSpec(TAG_LENGTH_BITS, iv);
cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmSpec);
int encryptedLength = data.length - IV_LENGTH_BYTES;
byte[] encrypted = new byte[encryptedLength];
System.arraycopy(data, 0, encrypted, 0, encryptedLength);
byte[] tag = new byte[IV_LENGTH_BYTES];
System.arraycopy(data, encryptedLength, tag, 0, IV_LENGTH_BYTES);
cipher.updateAAD(tag);
return cipher.doFinal(encrypted);
}
private static byte[] hexToBytes(String hex) {
byte[] bytes = new byte[hex.length() / 2];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer.parseInt(hex.substring(i * 2, i * 2 + 2), 16);
}
return bytes;
}
private static byte[] generateRandomBytes(int length) {
byte[] bytes = new byte[length];
new SecureRandom().nextBytes(bytes);
return bytes;
}
}
```
在上面的示例中,我们使用JCE提供的javax.crypto.Cipher类实现了GCM加密和解密的功能。首先,我们定义了`encrypt`和`decrypt`两个函数,分别用于加密和解密。在加密函数中,我们首先使用`Cipher.getInstance`方法获取AES/GCM/NoPadding的Cipher实例,并使用`SecretKeySpec`和`GCMParameterSpec`分别设置密钥和初始化向量。然后,我们调用`Cipher.init`方法进行初始化,并使用`Cipher.doFinal`方法进行加密。最后,我们将加密结果和完整性校验值拼接在一起返回。
在解密函数中,我们首先使用`Cipher.getInstance`方法获取AES/GCM/NoPadding的Cipher实例,并使用`SecretKeySpec`和`GCMParameterSpec`分别设置密钥和初始化向量。然后,我们从输入数据中分离出加密结果和完整性校验值,并使用`Cipher.updateAAD`方法设置解密所需的完整性校验值。最后,我们调用`Cipher.doFinal`方法进行解密,并返回解密后的数据。
最后,我们使用示例数据进行加密和解密,并输出结果。
阅读全文