AES-GCM算法 Java与Python互相加解密

这篇具有很好参考价值的文章主要介绍了AES-GCM算法 Java与Python互相加解密。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. AES

AES加密算法全称是Advanced Encryption Standard(高级加密标准),是美国NIST在2001年发布的,旨在代替DES称为广泛使用的标准。AES是一种对称分组密码算法。

2. AES的分组长度和秘钥长度

AES的明文分组长度为128位(16字节),密钥长度可以为128位(16字节)、192位(24字节)、256位(32字节),根据密钥长度的不同,AES分为AES-128、AES-192、AES-256三种。

不同的秘钥长度带来的不同是什么?
AES加密体制也是由多轮加密构成,除了结尾的一轮,其他轮都是由四个步骤组成——字节代替、行移位、列混淆、轮密钥加。而最后一轮仅包括字节代替、行移位、轮密钥加这三步。AES迭代的轮数与密钥的长度相关,16字节的密钥对应着迭代10轮,24字节的密钥对应着迭代12轮,32字节的密钥对应着迭代14轮。在开始所有轮迭代之前,需要进行一次初始变换——一次轮密钥加,这一步往往被称为第0轮。

3.AES加密模式

模式 优点 缺点 用途
ECB(Electronic Mode 电子密码本模式) 简单、可并行计算、误差不传递 不能隐藏明文模式(比如图像加密轮廓仍在)、主动攻击(改明文,后续内容不影响,只要误差不传递该缺点就存在) 需要并行加密的应用
CFB(CipherFeedback,密码反馈) 不容易主动攻击(误差传递)、适合长报文,是SSL、IPSec标准 无法并行、误差传递 长报文传输,SSL和IPSec
OFB (OutputFeedback,输出反馈) 不容易主动攻击(误差传递),分组转变为流模式,可加密小于分组数据 无法并行、误差传递
CTR(Counter,计数器模式) 并行、一次一密、不传递误差 主动攻击(改明文,后续内容不影响,只要误差不传递该缺点就存在)

4.AES-GCM

GCM即Galois/Counter Mode,指的是加密采用Counter模式,并且带有GMAC消息认证码。
这个Counter模式,粗略概括来说,就是对一个逐次累加的计数器进行加密,然后用加密后的比特序列与明文分组进行异或得到密文。GMAC消息认证码的作用就是为了验证数据的完整性。

由于本文不是密码学相关,只是单纯使用这个算法,故不做深入探究如何加密的过程。接下来,演示Java中如何使用AES-GCM算法。

5. JAVA应用

5.1 生成密钥

 public void generateSecret() throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(256);

        SecretKey key = keyGenerator.generateKey();
        byte[] bytes = key.getEncoded();
        System.out.println(Base64.getEncoder().encodeToString(bytes));
    }

这里生成256位长度的密钥,然后将密钥使用base64编码成字符串。

5.2 加密

public String encrypt(String plaintext, String secretString) throws Exception {
        byte[] IV = new byte[12];
        SecureRandom random = new SecureRandom();
        random.nextBytes(IV);

        byte[] secretKey = Base64.getDecoder().decode(secretString);
        SecretKeySpec keySpec = new SecretKeySpec(secretKey, "AES");
        GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, IV);

        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec);

        byte[] cipherText = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
        ByteBuffer byteBuffer = ByteBuffer.allocate(IV.length + cipherText.length);
        byteBuffer.put(IV);
        byteBuffer.put(cipherText);
        return Base64.getEncoder().encodeToString(byteBuffer.array());
    }

这里使用了随机向量IV,IV的作用是保证即使是相同的明文,使用相同的密钥进行加密,也会使每次加密得到的密文结果不相同。
这里要做几点说明:

    1. IV向量的长度为何是12字节?AES-GCM recommended IV size: Why 12 bytes?这篇文章给出了解答,总结起来就是两个字:高效。

96-bit IV values can be processed more efficiently, so that [ed: this] length is recommended for situations in which efficiency is critical.

    1. 消息验证器MAC在哪里?MAC在加密好的密文之中,在密文的最后16个字节里。由于JAVA做了封装,很多人会忽略这一点,以为dofinal得出的就是密文,这个ciphertext当中包含了MAC。

5.3 解密

public String decrypt(String ciphertext, String secretString) throws Exception {
        byte[] encrypted = Base64.getDecoder().decode(ciphertext);
        byte[] IV = Arrays.copyOfRange(encrypted, 0, 12);
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

        GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, IV);
        byte[] secretKey = Base64.getDecoder().decode(secretString);
        SecretKeySpec keySpec = new SecretKeySpec(secretKey, "AES");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);

        byte[] plaintext = cipher.doFinal(Arrays.copyOfRange(encrypted, 12, encrypted.length));
        return new String(plaintext);
    }

由于我把IV也保存在了密文当中,因此要先把IV的内容取出来,拿剩下的内容进行解密。

6. Python应用

JAVA有的,我大Python也要有!(更主要的原因是,有不同语言加解密的场景)
Python3这里使用了一个库pycryptodome,没有的需要安装一下:

pip3 install pycryptodome

Python程序如下:

from Crypto.Cipher import AES
import base64
import os
import sys

encoding_utf8 = 'utf-8'

def aes_gcm_encrypt(plaintext, secret):
    secret_key = base64.b64decode(secret)
    iv = os.urandom(12)
    aes_cipher = AES.new(secret_key, AES.MODE_GCM, iv)
    ciphertext, auth_tag = aes_cipher.encrypt_and_digest(plaintext.encode(encoding_utf8))
    result = iv + ciphertext + auth_tag
    return base64.b64encode(result).decode(encoding_utf8)


def aes_gcm_decrypt(encrypted, secret_key):
    res_bytes = base64.b64decode(encrypted.encode(encoding_utf8))
    nonce = res_bytes[:12]
    ciphertext = res_bytes[12:-16]
    auth_tag = res_bytes[-16:]
    aes_cipher = AES.new(base64.b64decode(secret_key), AES.MODE_GCM, nonce)
    return aes_cipher.decrypt_and_verify(ciphertext, auth_tag).decode(encoding_utf8)


def aes_gcm_generate_secret():
    random_bytes = os.urandom(32)
    return base64.b64encode(random_bytes).decode(encoding_utf8)

7. 测试一下

public static void main(String[] args) throws Exception {
        AESGCM util = new AESGCM();
        String ciphertext = util.encrypt("hello world", "lLbIsDo9GmxgKbjzsjzDWS7EiLOiXKAdhaaQIhCpKao=");
        System.out.println(util.decrypt(ciphertext, "lLbIsDo9GmxgKbjzsjzDWS7EiLOiXKAdhaaQIhCpKao="));
    }

这里使用Python生成里密钥,并使用JAVA密钥加密解密。可以得到准确的密文。Python和JAVA可以互相使用密钥进行加解密。文章来源地址https://www.toymoban.com/news/detail-653320.html

到了这里,关于AES-GCM算法 Java与Python互相加解密的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • AES加密解密python实现

            关于现代密码学算法,可以查看以下博客全面了解 CISSP考试要求里的“应用密码学”内容辅助记忆趣味串讲_晓翔仔的博客-CSDN博客         AES的细节知识,可以查阅 AES加密算法的详细介绍与实现_TimeShatter的博客-CSDN博客          AES 加密最常用的模式就是

    2024年02月05日
    浏览(79)
  • Python对AES进行加密和解密的多种方法

    前言 本文是该专栏的第24篇,后面会持续分享python的各种干货知识,值得关注。 做过爬虫项目的同学,对AES加解密都有遇到过。 在密码学中,加密算法也分为双向加密和单向加密。单向加密包括MD5、SHA等摘要算法,它们是不可逆的。而双向加密包括 对称加密 和 非对称加密

    2023年04月14日
    浏览(40)
  • 用java语言写一个AES算法,使用AES(CBC模式)对数据进行加密或解密。加解密用到的密钥(Key)和密钥偏移量(IV),代码实例类编写。

    以下是一个使用Java编写的AES算法实例,使用AES(CBC模式)对数据进行加密和解密。代码中包括了生成随机密钥和密钥偏移量的方法。 java Copy code import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.InvalidAlgorithmParameterException; import

    2024年02月07日
    浏览(63)
  • AES对称加密实战——前端js加密后端python解密

    高级加密标准(AES, Advanced Encryption Standard),是一种最常见的对称加密算法 。其加密流程如下图所示,发送方通过密钥对明文加密后进行网络传输,接收方用同样的密钥将密文解密。在前后端通讯场景中,可利用AES算法对用户密码进行加密后传输,防止被抓包而造成密码泄露。

    2024年02月04日
    浏览(61)
  • AES与DES加密解密算法

    AES(Advanced Encryption Standard,高级加密标准)的出现,是因为以前使用的DES算法密钥长度较短,已经不适应当今数据加密安 全性的要求,因此2000年10月2日,美国政府宣布将比利时密码学家Joan Daemen和Vincent Rijmen提出的密码算法RIJNDAEL作为高级加密标准。2001年11月26日,美国政府

    2024年04月28日
    浏览(53)
  • 20.3 OpenSSL 对称AES加解密算法

    AES算法是一种对称加密算法,全称为高级加密标准(Advanced Encryption Standard)。它是一种分组密码,以 128 比特为一个分组进行加密,其密钥长度可以是 128 比特、 192 比特或 256 比特,因此可以提供不同等级的安全性。该算法采用了替代、置换和混淆等技术,以及多轮加密和密

    2024年02月08日
    浏览(42)
  • python实现rsa\aes\sm2\sm4加解密

    相关依赖: gmssl==3.2.2 pycryptodome == 3.9.7 基类: Rsa分段加解密实现(适用于pkcs1/8格式的2048bit私钥): AES加解密: SM2加解密: SM4加解密: 利用枚举扩展: 使用:

    2024年02月16日
    浏览(35)
  • java:AES加密和解密

    1 前言 对称加密,即单秘钥加密,指加密和解密的过程中,使用相同的秘钥,相比于非对称加密,因仅有一把钥匙,故而速度更快,更适合解密大文件(常见于如视频文件的加密解密中)。AES算法就属于对称加密中的一种。 2 使用 依赖引入: AES加密与解密的工具类封装: 执

    2024年02月11日
    浏览(59)
  • 前端CryptoJS-AES加解密 对应php的AES-128-CBC加解密踩坑(java也相同加解密)

     前端部分注意看填充是pkcs7 有个前提,要看前端有没有转成hex格式,如果没转,php那边就不需要调用特定函数转hex格式的 后端php代码

    2024年02月15日
    浏览(55)
  • SM4、AES、DES加解密算法性能比较

    加密算法 文件大小 加密耗时(ms) 解密耗时(ms) SM4 5M 1596 841 AES 5M 201 447 DES 5M 317 669 SM4 620KB 689 172 AES 620KB 109 186 DES 620KB 53 132 SM4 36KB 487 34 AES 36KB 20 57 DES 36KB 9 14 SM4 6Bytes 505 0 AES 6Bytes 13 24 DES 6Bytes 1 0

    2024年02月13日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包