序文
転送パラメータではなく、平文の送信、インターフェイスの暗号化の最初は、返されたデータも返すように暗号化されている場合にインターフェースのいくつかの企業のセキュリティ要件は、比較的高いです。
現在、多くの一般的な暗号化はAES / CBC / pkcs7paddingです。
五種類のAES暗号化モード
一般的に、 "AES / ECB / NoPadding"または"AES / ECB / PKCS5Padding"変換または"AES / ECB / PKCS5Padding"変換モード使用する場合はAES暗号化、
CBCやCFB:ECBモードでAES暗号化を使用して、明示的に暗号化アルゴリズムを指定しますモードでは、あなたはPKCS5Paddingがいっぱいもたらすことができます。AES 128ビットの鍵長が最小推奨256
暗号化AES-ECBモード暗号化および復号化は、各暗号化前後の、初期化ベクトル(初期ベクトルIV)を必要とする、または復号し、平文または暗号で初期化ベクトルを使用して温家宝XOR。
5つのブロック暗号システムの仕事があります。
- 1.コードブックモード(電子コードブックブック(ECB));
- 2.暗号ブロック連鎖モード(暗号ブロック連鎖(CBC))。
- 3.電卓モード(カウンタ(CTR))。
- 4.暗号フィードバックモード(暗号帰還型(CFB))。
- 5.出力フィードバックモード(出力フィードバック(OFB))
AESアルゴリズムは、典型的な対称暗号化アルゴリズム[]は、いわゆる対称暗号化は、暗号化と復号鍵が同じであることです
JAVAの暗号化
一般的に、我々は、インタフェースがJavaで書かれているインタフェースの自動テストを行うため、Javaの下に暗号化を理解するために来ます。あなたは、Java対応する暗号化の方法を知っている、とのpythonで対応する解毒剤を見つけるために!
/**
*
* @author ngh
* AES128 算法
*
* CBC 模式
*
* PKCS7Padding 填充模式
*
* CBC模式需要添加一个参数iv
*
* 介于java 不支持PKCS7Padding,只支持PKCS5Padding 但是PKCS7Padding 和 PKCS5Padding 没有什么区别
* 要实现在java端用PKCS7Padding填充,需要用到bouncycastle组件来实现
*/
public class AES {
// 算法名称
final String KEY_ALGORITHM = "AES";
// 加解密算法/模式/填充方式
final String algorithmStr = "AES/CBC/PKCS7Padding";
//
private Key key;
private Cipher cipher;
boolean isInited = false;
byte[] iv = { 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38 };
public void init(byte[] keyBytes) {
// 如果密钥不足16位,那么就补足. 这个if 中的内容很重要
int base = 16;
if (keyBytes.length % base != 0) {
int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);
byte[] temp = new byte[groups * base];
Arrays.fill(temp, (byte) 0);
System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
keyBytes = temp;
}
// 初始化
Security.addProvider(new BouncyCastleProvider());
// 转化成JAVA的密钥格式
key = new SecretKeySpec(keyBytes, KEY_ALGORITHM);
try {
// 初始化cipher
cipher = Cipher.getInstance(algorithmStr, "BC");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchProviderException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 加密方法
*
* @param content
* 要加密的字符串
* @param keyBytes
* 加密密钥
* @return
*/
public byte[] encrypt(byte[] content, byte[] keyBytes) {
byte[] encryptedText = null;
init(keyBytes);
System.out.println("IV:" + new String(iv));
try {
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
encryptedText = cipher.doFinal(content);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return encryptedText;
}
/**
* 解密方法
*
* @param encryptedData
* 要解密的字符串
* @param keyBytes
* 解密密钥
* @return
*/
public byte[] decrypt(byte[] encryptedData, byte[] keyBytes) {
byte[] encryptedText = null;
init(keyBytes);
System.out.println("IV:" + new String(iv));
try {
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
encryptedText = cipher.doFinal(encryptedData);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return encryptedText;
}
}
テスト
ublic class Test {
public static void main(String[] args) {
AES aes = new AES();
// 加解密 密钥
byte[] keybytes = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38 };
String content = "1";
// 加密字符串
System.out.println("加密前的:" + content);
System.out.println("加密密钥:" + new String(keybytes));
// 加密方法
byte[] enc = aes.encrypt(content.getBytes(), keybytes);
System.out.println("加密后的内容:" + new String(Hex.encode(enc)));
// 解密方法
byte[] dec = aes.decrypt(enc, keybytes);
System.out.println("解密后的内容:" + new String(dec));
}
テスト結果
测试结果:
加密前的:1
加密密钥:12345678
IV:0102030405060708
加密后的内容:b59227d86200d7fedfb8418a59a8eea9
IV:0102030405060708
解密后的内容:1
Pythonの暗号化
このセクションでは上記のJavaコードから、私たちは、重要な情報を知っておく必要があり、暗号化方式:AES/CBC/PKCS7Padding
IVは、オフセットがbyte[] iv = { 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38 }
0x30
0進数で、IV = b'0102030405060708」、IV、通常16個の
キーのキー上記試験中キーは12345678ですが、キーは不十分と判断場合があるので、それの上に、通常は16で16 \ 0を埋めるためにする場合、
そのキーは次のようになります。12345678 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0
PythonコードAES / CBC / pkcs7padding解読
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import algorithms
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
import json
'''
AES/CBC/PKCS7Padding 加密解密
环境需求:
pip3 install pycryptodome
'''
class PrpCrypt(object):
def __init__(self, key='0000000000000000'):
self.key = key.encode('utf-8')
self.mode = AES.MODE_CBC
self.iv = b'0102030405060708'
# block_size 128位
# 加密函数,如果text不足16位就用空格补足为16位,
# 如果大于16但是不是16的倍数,那就补足为16的倍数。
def encrypt(self, text):
cryptor = AES.new(self.key, self.mode, self.iv)
text = text.encode('utf-8')
# 这里密钥key 长度必须为16(AES-128),24(AES-192),或者32 (AES-256)Bytes 长度
# 目前AES-128 足够目前使用
text=self.pkcs7_padding(text)
self.ciphertext = cryptor.encrypt(text)
# 因为AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题
# 所以这里统一把加密后的字符串转化为16进制字符串
return b2a_hex(self.ciphertext).decode().upper()
@staticmethod
def pkcs7_padding(data):
if not isinstance(data, bytes):
data = data.encode()
padder = padding.PKCS7(algorithms.AES.block_size).padder()
padded_data = padder.update(data) + padder.finalize()
return padded_data
@staticmethod
def pkcs7_unpadding(padded_data):
unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
data = unpadder.update(padded_data)
try:
uppadded_data = data + unpadder.finalize()
except ValueError:
raise Exception('无效的加密信息!')
else:
return uppadded_data
# 解密后,去掉补足的空格用strip() 去掉
def decrypt(self, text):
# 偏移量'iv'
cryptor = AES.new(self.key, self.mode, self.iv)
plain_text = cryptor.decrypt(a2b_hex(text))
# return plain_text.rstrip('\0')
return bytes.decode(plain_text).rstrip("\x01").\
rstrip("\x02").rstrip("\x03").rstrip("\x04").rstrip("\x05").\
rstrip("\x06").rstrip("\x07").rstrip("\x08").rstrip("\x09").\
rstrip("\x0a").rstrip("\x0b").rstrip("\x0c").rstrip("\x0d").\
rstrip("\x0e").rstrip("\x0f").rstrip("\x10")
def dict_json(self, d):
'''python字典转json字符串, 去掉一些空格'''
j = json.dumps(d).replace('": ', '":').replace(', "', ',"').replace(", {", ",{")
return j
# 加解密
if __name__ == '__main__':
import json
pc = PrpCrypt('12345678\0\0\0\0\0\0\0\0') # 初始化密钥
a = "1"
print("加密前:%s" % a)
b = pc.encrypt(a)
print("解密后:%s" % b)
print("大写变小写:%s" % b.lower())
最後に、営業成績
加密前:1
解密后:B59227D86200D7FEDFB8418A59A8EEA9
大写变小写:b59227d86200d7fedfb8418a59a8eea9
関連するブログを参照してください。https://www.cnblogs.com/chen-lhx/p/6233954.html
https://blog.csdn.net/weixin_43107613/article/details/87875359