id-aes128-GCM 加解密example

id-aes128-GCM 比较好的地方是可以选用NoPadding。

 

AES-GCM

The Galois/Counter Mode (GCM) is specified in [GCM]. GCM is a generic authenticated encryption block cipher mode. GCM is defined for use with any 128-bit block cipher, but in this document, GCM is used with the AES block cipher. AES-GCM has four inputs: an AES key, an initialization vector (IV), a plaintext content, and optional additional authenticated data (AAD). AES-GCM generates two outputs: a ciphertext and message authentication code (also called an authentication tag). To have a common set of terms for AES-CCM and AES-GCM, the AES-GCM IV is referred to as a nonce in the remainder of this document. The nonce is generated by the party performing the authenticated encryption operation. Within the scope of any authenticated- encryption key, the nonce value MUST be unique. That is, the set of nonce values used with any given key MUST NOT contain any duplicate values. Using the same nonce for two different messages encrypted with the same key destroys the security properties. AAD is authenticated but not encrypted. Thus, the AAD is not included in the AES-GCM output. It can be used to authenticate plaintext packet headers. In the CMS authenticated-enveloped-data content type, authenticated attributes comprise the AAD.

 

示例代码如下:

 

复制代码
 1 import org.apache.commons.codec.binary.Hex;
 2 import org.bouncycastle.jce.provider.BouncyCastleProvider;
 3 
 4 import java.nio.ByteBuffer;
 5 import java.nio.charset.StandardCharsets;
 6 import java.security.*;
 7 
 8 import javax.crypto.*;
 9 
10 import lombok.extern.slf4j.Slf4j;
11 
12 
13 @Slf4j
14 public class AESGCMExample {
15 
16     private static final byte[] SECRET_KEY_BYTE = {88, -91, -8, -75, 63, -16, 16, -90, 46, -78, -23, -125, 3, -9, -46, -48};
17     private static final SecretKey SECRET_KEY = new SecretKeySpec(SECRET_KEY_BYTE, "AES");
18 
19     private static final byte[] OFFSET_IV = {-120, -77, 95, -88, -73, 88, 121, 119, 119, -37, -81, -88, 29, -13, -68, -97};
20 
21     private static final String CIPHER_TYPE = "AES/GCM/NoPadding";
22 
23     static {
24         Security.addProvider(new BouncyCastleProvider());
25     }
26 
27     public static byte[] encrypt(String data) {
28         try {
29             Cipher cipher = Cipher.getInstance(CIPHER_TYPE);
30 
31             AlgorithmParameterSpec parameterSpec = new GCMParameterSpec(128, OFFSET_IV); //128 bit auth tag length
32             cipher.init(Cipher.ENCRYPT_MODE, SECRET_KEY, parameterSpec);
33 
34             byte[] cipherText = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
35             ByteBuffer byteBuffer = ByteBuffer.allocate(OFFSET_IV.length + cipherText.length);
36             byteBuffer.put(OFFSET_IV);
37             byteBuffer.put(cipherText);
38             return byteBuffer.array();
39         } catch (NoSuchAlgorithmException
40                 | NoSuchPaddingException
41                 | InvalidKeyException
42                 | InvalidAlgorithmParameterException
43                 | IllegalBlockSizeException
44                 | BadPaddingException e) {
45             log.error("AES failed to encrypt", e);
46         }
47         return null;
48     }
49 
50     public static String decrypt(byte[] cipherMessage) {
51         try {
52             final Cipher cipher = Cipher.getInstance(CIPHER_TYPE);
53             AlgorithmParameterSpec gcmIv = new GCMParameterSpec(128, cipherMessage, 0, OFFSET_IV.length);
54             cipher.init(Cipher.DECRYPT_MODE, SECRET_KEY, gcmIv);
55             byte[] plainText = cipher.doFinal(cipherMessage, OFFSET_IV.length, cipherMessage.length - OFFSET_IV.length);
56             return new String(plainText, StandardCharsets.UTF_8);
57         } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException |
58                 InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {
59             log.error("AES failed to decrypt", e);
60         }
61         return null;
62     }
63 
64     public static void main(String args[]) throws Exception {
65         String originPlainText = "{\"Hello\": \"World\"}";
66         byte[] cipherText = encrypt(originData);
67         System.out.println(Hex.encodeHexString(cipherText));
68         String plainText = decrypt(cipherText);
69         System.out.println(plainText);
70     }
71 
72 }
复制代码

 



posted @   walle搬砖  阅读(1106)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示