java-python aes-gcm 加密说明

python-java 的 AES-GCM 加解说明

内容

  1. 说明
  2. 测试数据
  3. python-PyCryptodome版本
  4. python-cryptography版本
  5. java版本

说明

  1. AES-GCM是一种NIST标准的认证加密算法, 是一种能够同时保证数据的保密性、 完整性和真实性的一种加密模式。它最广泛的应用是在TLS中。
  2. GCM详细说明
测试数据
AES加密模式:AEAD_AES_256_GCM

AES密钥:
aesKey = 1d35eefc2b8207d615028d056ce5296c
附加数据:
associatedData = 12345
随机数据:nonceData
nonceData = 1234567812345678
数据明文: 1234561234565
数据密文:X3lkQaqdASpIF0+XsOjwUhfCZdvXh3RQFXsH8o8=

python demo--PyCryptodome版本
import base64
from Crypto.Cipher import AES

aes_key = '1d35eefc2b8207d615028d056ce5296c'
associatedData = "12345"
nonce = "1234567812345678"

def aes_en_gcm_func():
    de_data = '1234561234565'
    cipher = AES.new(aes_key.encode(), AES.MODE_GCM, nonce=nonce.encode())
    cipher.update(associatedData.encode())
    ct, tag = cipher.encrypt_and_digest(de_data.encode('utf-8'))
    return base64.b64encode(ct + tag).decode('utf-8')


def aes_de_gcm_func():
    en_data = 'X3lkQaqdASpIF0+XsOjwUhfCZdvXh3RQFXsH8o8='
    cipher = AES.new(aes_key.encode(), AES.MODE_GCM, nonce=nonce.encode())
    cipher.update(associatedData.encode())
    en_data = base64.b64decode(en_data.encode('utf-8'))
    auth_tag = en_data[-16:]
    _en_data = en_data[:-16]
    plaintext = cipher.decrypt_and_verify(_en_data, auth_tag)
    return plaintext.decode()
python demo--cryptography 版本
import base64
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

aes_key = '1d35eefc2b8207d615028d056ce5296c'
associatedData = "12345"
nonce = "1234567812345678"

def st_aes_en_func():
    de_data = '1234561234565'
    aesgcm = AESGCM(aes_key.encode())
    ct = aesgcm.encrypt(nonce.encode(), de_data.encode(), associatedData.encode())
    return base64.b64encode(ct).decode('utf-8')


def st_aes_de_func():
    en_data = 'X3lkQaqdASpIF0+XsOjwUhfCZdvXh3RQFXsH8o8='
    en_data = base64.b64decode(en_data.encode('utf-8'))
    aesgcm = AESGCM(aes_key.encode())
    ct = aesgcm.decrypt(nonce.encode(), en_data, associatedData.encode())
    return ct.decode()
java demo
package tools;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AesUtil {
    static final int KEY_LENGTH_BYTE = 32;
    static final int TAG_LENGTH_BIT = 128;
    private final byte[] aesKey;

    public AesUtil(byte[] key) {
        if (key.length != KEY_LENGTH_BYTE) {
            throw new IllegalArgumentException("无效的ApiV3Key,长度必须为32个字节");
        }
        this.aesKey = key;
    }

    public String decryptToString(byte[] associatedData, byte[] nonce, String ciphertext)
            throws GeneralSecurityException, IOException {
        try {
            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

            SecretKeySpec key = new SecretKeySpec(aesKey, "AES");
            GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce);

            cipher.init(Cipher.DECRYPT_MODE, key, spec);
            cipher.updateAAD(associatedData);

            return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), "utf-8");
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            throw new IllegalStateException(e);
        } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
            throw new IllegalArgumentException(e);
        }
    }

    public String encryptToString(byte[] associatedData, byte[] nonce, String ciphertext)
            throws GeneralSecurityException, IOException{
        try {
            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

            SecretKeySpec key = new SecretKeySpec(aesKey, "AES");
            GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce);

            cipher.init(Cipher.ENCRYPT_MODE, key, spec);
            cipher.updateAAD(associatedData);

//            return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), "utf-8");
            return new String(Base64.getEncoder().encode(cipher.doFinal(ciphertext.getBytes())), "utf-8");
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            throw new IllegalStateException(e);
        } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
            throw new IllegalArgumentException(e);
        }
    }
    public static void main(String[] args) throws Exception {
        String key = "1d35eefc2b8207d615028d056ce5296c";
        String associatedData = "12345";
        String nonce = "1234567812345678";
        AesUtil aesUtils = new AesUtil(key.getBytes());

        String enData = aesUtils.encryptToString(associatedData.getBytes(), nonce.getBytes(), "1234561234565");
        System.out.println("加密后密文:" + enData);
        String deData = aesUtils.decryptToString(associatedData.getBytes(), nonce.getBytes(), enData);
        System.out.println("解密后明文:" + deData);

    }

}


  • 参考
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 本人在java中运行的一段AES加密代码,采用的是GCM加密模式,出于某种原因需要将这部分代码移植到python项...
    Halis_123阅读 6,713评论 3 2
  • AES是一种对称加密算法,可以参考:https://blog.csdn.net/qq_28205153/artic...
    阿帮I3阅读 3,656评论 0 3
  • 本篇主要介绍笔者在iOS开发工作中用到的加解密算法的使用,主要包括:1)对称加密算法:AES、DES、3DES2)...
    江山风雨阅读 5,295评论 1 5
  • 以太坊Whisper协议中,默认的对称加密使用的是AES-GCM加密算法。 AES是一种对称加密算法,它的相关概念...
    叫我null阅读 1,923评论 0 1
  • window下安装 1.安装python 下载python-3.7.0-amd64.exe,直接下一步安装,记得勾...
    Creator_Ly阅读 1,281评论 0 0

友情链接更多精彩内容