热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

javaAES/ECB/PKCS5padding加密转换Python3

javaAESECBPKCS5padding加密转换Python3-javaAESECBPKCS5padding加密转换Python

java AES/ECB/PKCS5padding 加密 转换Python

注意:加密方式128位AES加密模式为ECB进行加密,加密后使用Base64转码。

最近和java项目对接遇到AES加密算法,java代码有SecureRandom.getInstance("SHA1PRNG"); 转换成Python

AES加密

高级加密标准(Advanced Encryption Standard: AES)是美国国家标准与技术研究院(NIST)在2001年建立了电子数据的加密规范。
其是对称加解密算法的最经典算法之一,它是一种分组加密标准,每个加密块大小为128位,允许的密钥长度为128、192和256位。这里只介绍ECB加密模式。

AES加密模式:ECB/CBC/CTR/OFB/CFB
填充:pkcs5padding/pkcs7padding/zeropadding/iso10126/ansix923
数据块:128位/192位/256位

ECB模式

ECB模式作为最简单的工作模式,直接将明文分组,每组分别加密,每个分组独立且前后文无关

Java 默认加密demo

Java默认AES加密模式是"AES/ECB/PKCS5Padding"。

java代码展示

package com.qzd.hit.util;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class Demo {

    /*** main
    * @author qizai
    * data: params
    * encStr: Here, the length of the key must be a multiple of 16
    */
    public static void main(String[] args) throws Exception {
        // Encrypt Data
        String key = "ROcb6JybnKILLOlO"; // Secret Key length must be (16 24 32)
        String data = "[\"123456789\"]"; // Content to be encrypted
        String encStr = encrypt(data, key);  // Content to be decrypted
        System.out.println(encStr); //Encrypted data: w6oijM0xddQrItnH3UybLQ==
        // Decrypt Data
        String decStr = decrypt(encStr, key);
        System.out.println(decStr); //Decrypted data: ["123456789"]
    }

    public static String encrypt(String content, String password) {
        if (StringUtils.isEmpty(content) || StringUtils.isEmpty(password)) {
            System.out.println("AES encryption params is null");
            return null;
        }
        try {
            // Create cipher
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            byte[] byteCOntent= content.getBytes("UTF-8");
            // Initialize as cryptographic cipher
            cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(password));
            byte[] encryptByte = cipher.doFinal(byteContent);
            return org.apache.commons.codec.binary.Base64.encodeBase64String(encryptByte);
        } catch (Exception e) {
            System.out.println("AES encryption operation has exception,content:{},password:{}", content, password, e);
        }
        return null;
    }

    public static String decrypt(String encryptContent, String password) throws Exception {
        if (StringUtils.isEmpty(encryptContent) || StringUtils.isEmpty(password)) {
            System.out.println("AES The request parameter is null");
            return null;
        }
        Cipher cipher = null;
        cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        // Set to decryption mode
        cipher.init(Cipher.DECRYPT_MODE, getSecretKey(password));
        // Perform decryption operation
        byte[] result = cipher.doFinal(org.apache.commons.codec.binary.Base64.decodeBase64(encryptContent));
        return new String(result, "UTF-8");
    }

    private static SecretKeySpec getSecretKey(final String password) throws NoSuchAlgorithmException {
        // Generates the generator for the specified algorithm key
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        random.setSeed(password.getBytes());
        keyGenerator.init(128, random);
        // Grnerate Key
        SecretKey secretKey = keyGenerator.generateKey();
        // Key converted to AES
        return new SecretKeySpec(secretKey.getEncoded(), "AES");
    }
}

加密注意点:

KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); // Generates the generator for the specified algorithm key
SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); // SHA1PRNG Random number algorithm
random.setSeed(password.getBytes());
keyGenerator.init(128, random);
SecretKey secretKey = keyGenerator.generateKey();

Python 实现AES/ECB/PKCS5padding

安装AES相关库(window下)

pip install pycryptodome

Linux下安装

pip install pycrypto

相关代码实现步骤

import base64
import hashlib

import requests
from Crypto.Cipher import AES as _AES


class AES:

    def __init__(self, key: str):
        """Init aes object used by encrypt or decrypt.
        AES/ECB/PKCS5Padding  same as aes in java default.
        """

        self.aes = _AES.new(self.get_sha1prng_key(key), _AES.MODE_ECB)

    @staticmethod
    def get_sha1prng_key(key: str) -> bytes:
        """encrypt key with SHA1PRNG.
        same as java AES crypto key generator SHA1PRNG.
        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );
        secureRandom.setSeed(decryptKey.getBytes());
        keygen.init(128, secureRandom);
        :param string key: original key.
        :return bytes: encrypt key with SHA1PRNG, 128 bits or 16 long bytes.
        """

        signature: bytes = hashlib.sha1(key.encode()).digest()
        signature: bytes = hashlib.sha1(signature).digest()
        return signature[:16]

    @staticmethod
    def padding(s: str) -> str:
        """Padding PKCS5"""

        pad_num: int = 16 - len(s) % 16
        return s + pad_num * chr(pad_num)

    @staticmethod
    def unpadding(s):
        """Unpadding PKCS5"""

        padding_num: int = ord(s[-1])
        return s[: -padding_num]

    def encrypt_to_bytes(self, content_str):
        """From string encrypt to bytes ciphertext.
        """

        content_bytes = self.padding(content_str).encode()
        ciphertext_bytes = self.aes.encrypt(content_bytes)
        return ciphertext_bytes

    def encrypt_to_base64(self, content_str):
        """From string encrypt to base64 ciphertext.
        """

        ciphertext_bytes = self.encrypt_to_bytes(content_str)
        ciphertext_bs64 = base64.b64encode(ciphertext_bytes).decode()
        return ciphertext_bs64

    def decrypt_from_bytes(self, ciphertext_bytes):
        """From bytes ciphertext decrypt to string.
        """

        content_bytes = self.aes.decrypt(ciphertext_bytes)
        content_str = self.unpadding(content_bytes.decode())
        return content_str

    def decrypt_from_base64(self, ciphertext_bs64):
        """From base64 ciphertext decrypt to string.
        """

        ciphertext_bytes = base64.b64decode(ciphertext_bs64)
        content_str = self.decrypt_from_bytes(ciphertext_bytes)
        return content_str


def encrypt_to_bytes(content_str, encrypt_key: str):
    """From string encrypt to bytes ciphertext.
    """

    aes: AES = AES(encrypt_key)
    ciphertext_bytes = aes.encrypt_to_bytes(content_str)
    return ciphertext_bytes


def encrypt_to_base64(content_str, encrypt_key: str) -> str:
    """From string encrypt to base64 ciphertext.
    """

    aes: AES = AES(encrypt_key)
    ciphertext_bs64 = aes.encrypt_to_base64(content_str)
    return ciphertext_bs64


def decrypt_from_bytes(ciphertext_bytes, decrypt_key: str) -> str:
    """From bytes ciphertext decrypt to string.
    """

    aes: AES = AES(decrypt_key)
    content_str = aes.decrypt_from_bytes(ciphertext_bytes)
    return content_str


def decrypt_from_base64(ciphertext_bs64, decrypt_key: str) -> str:
    """From base64 ciphertext decrypt to string.
    """

    aes: AES = AES(decrypt_key)
    content_str = aes.decrypt_from_base64(ciphertext_bs64)
    return content_str


if __name__ == "__main__":
    key = "iC6qfFyiza8aq"
    encrypt_str_data = "[\"13811111111\"]"
    et = encrypt_to_base64(encrypt_str_data, key)
    print("加密后数据: ", et)
    ret = decrypt_from_base64(et, key)
    print("解密后数据: ", ret)

关键代码

该方法实现了对key的转换,java中关键加密代码的内容,在这里返回为16进制字符串。

    @staticmethod
    def get_sha1prng_key(key: str) -> bytes:
        """encrypt key with SHA1PRNG.
        same as java AES crypto key generator SHA1PRNG.
        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );
        secureRandom.setSeed(decryptKey.getBytes());
        keygen.init(128, secureRandom);
        :param string key: original key.
        :return bytes: encrypt key with SHA1PRNG, 128 bits or 16 long bytes.
        """

        signature: bytes = hashlib.sha1(key.encode()).digest()
        signature: bytes = hashlib.sha1(signature).digest()
        return signature[:16]

简约版

import base64
import hashlib

from Crypto.Cipher import AES

SECRET_KEY = 'iC6qfFyiza8aq'  # 密钥


class AesEncrypt(object):
    def __init__(self):
        self.key = self.getKey(SECRET_KEY)
        self.mode = AES.MODE_ECB

    def pading(self, text):
        """对加密字符的处理"""
        return text + (len(self.key) - len(text) % len(self.key)) * chr(len(self.key) - len(text) % len(self.key))

    def unpading(self, text):
        """对解密字符的处理"""
        return text[0:-ord(text[-1:])]

    def getKey(self, key):
        """对key的处理,key 的长度 16,24,32"""
        signature: bytes = hashlib.sha1(key.encode()).digest()
        signature: bytes = hashlib.sha1(signature).digest()
        return signature[:16]

    def encrypt(self, text):
        """加密函数"""
        ecb_encrypt = AES.new(self.key, self.mode)  # ECB 模式
        ecb_text = ecb_encrypt.encrypt(bytes(self.pading(text), encoding="utf8"))
        encrypt_string = base64.b64encode(ecb_text).decode()
        return encrypt_string

    def decrypt(self, text):
        """解密函数"""
        decode = base64.b64decode(text)
        ecb_decrypt = AES.new(self.key, self.mode)  # ECB 模式
        plain_text = ecb_decrypt.decrypt(decode)
        decrypt_string = self.unpading(plain_text).decode()
        return decrypt_string


if __name__ == '__main__':
    aes_encrypt = AesEncrypt()
    data = "[\"13811111111\"]"
    en = aes_encrypt.encrypt(data)
    print("加密数据: ", en)
    dr = aes_encrypt.decrypt(en)
    print("解密数据: ", dr)

1. 对key进行sha1prng加密,就是文中的get_sha1prng_key方法,拿到加密后的密文当做AES的key

2. 确定AES的加密方式ECB,CBC 等 AES加密模式:ECB/CBC/CTR/OFB/CFB

3. 填充,key和原始文本都有可能填充,NoPadding,不填充,0填充,还有pkcs5padding, 不填充就是不对内容填充,直接加密,上面代码实现了\0填充和pkcs5padding 。

4. 总的来说加密内容对不上基本是key处理不一样或者填充不对。

【参考SHA1算法】


推荐阅读
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 本文介绍了在Win10上安装WinPythonHadoop的详细步骤,包括安装Python环境、安装JDK8、安装pyspark、安装Hadoop和Spark、设置环境变量、下载winutils.exe等。同时提醒注意Hadoop版本与pyspark版本的一致性,并建议重启电脑以确保安装成功。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • 开发笔记:Java是如何读取和写入浏览器Cookies的
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Java是如何读取和写入浏览器Cookies的相关的知识,希望对你有一定的参考价值。首先我 ... [详细]
  • 使用正则表达式爬取36Kr网站首页新闻的操作步骤和代码示例
    本文介绍了使用正则表达式来爬取36Kr网站首页所有新闻的操作步骤和代码示例。通过访问网站、查找关键词、编写代码等步骤,可以获取到网站首页的新闻数据。代码示例使用Python编写,并使用正则表达式来提取所需的数据。详细的操作步骤和代码示例可以参考本文内容。 ... [详细]
  • 延迟注入工具(python)的SQL脚本
    本文介绍了一个延迟注入工具(python)的SQL脚本,包括使用urllib2、time、socket、threading、requests等模块实现延迟注入的方法。该工具可以通过构造特定的URL来进行注入测试,并通过延迟时间来判断注入是否成功。 ... [详细]
  • 本文介绍了使用Spark实现低配版高斯朴素贝叶斯模型的原因和原理。随着数据量的增大,单机上运行高斯朴素贝叶斯模型会变得很慢,因此考虑使用Spark来加速运行。然而,Spark的MLlib并没有实现高斯朴素贝叶斯模型,因此需要自己动手实现。文章还介绍了朴素贝叶斯的原理和公式,并对具有多个特征和类别的模型进行了讨论。最后,作者总结了实现低配版高斯朴素贝叶斯模型的步骤。 ... [详细]
  • 大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记
    本文介绍了大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记,包括outputFormat接口实现类、自定义outputFormat步骤和案例。案例中将包含nty的日志输出到nty.log文件,其他日志输出到other.log文件。同时提供了一些相关网址供参考。 ... [详细]
  • 本文讨论了在shiro java配置中加入Shiro listener后启动失败的问题。作者引入了一系列jar包,并在web.xml中配置了相关内容,但启动后却无法正常运行。文章提供了具体引入的jar包和web.xml的配置内容,并指出可能的错误原因。该问题可能与jar包版本不兼容、web.xml配置错误等有关。 ... [详细]
  • Java如何导入和导出Excel文件的方法和步骤详解
    本文详细介绍了在SpringBoot中使用Java导入和导出Excel文件的方法和步骤,包括添加操作Excel的依赖、自定义注解等。文章还提供了示例代码,并将代码上传至GitHub供访问。 ... [详细]
  • 本文整理了Java中org.apache.solr.common.SolrDocument.setField()方法的一些代码示例,展示了SolrDocum ... [详细]
  • 写在前面最近在学习爬虫,在熟悉了Python语言和BeautifulSoup4后打算下个爬虫框架试试。没想到啊,这坑太深了。。。看了看相关介绍后选择了Scrapy框架,然后兴高采烈的 ... [详细]
  • 这篇文章给大家分享的是有关python3怎样中文转换编码的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。示例:处理 ... [详细]
author-avatar
646579262
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有