gpt4 book ai didi

Java-Python AES加密解密

转载 作者:行者123 更新时间:2023-12-02 09:46:58 29 4
gpt4 key购买 nike

我有一个使用 AES 来自 Java(v8) 的加密文本,我正在尝试使用相同的 SecretKey、Salt 在 python 中解密该文本,但在取消索引超出范围时遇到问题。当我执行相反的操作时,即在 python 中加密并在 java 中解密,那么我可以获得文本,但带有一些不需要的前缀。

以下是我尝试过的java和python代码。

Java 代码(来自 org.apache.commons.codec.binary.Base64 的 Base64)

public static String encrypt(String secretKey, String salt, String value) throws Exception {
Cipher cipher = initCipher(secretKey, salt, Cipher.ENCRYPT_MODE);
byte[] encrypted = cipher.doFinal(value.getBytes());
return Base64.encodeBase64String(encrypted);
}

public static String decrypt(String secretKey, String salt, String encrypted) throws Exception {
Cipher cipher = initCipher(secretKey, salt, Cipher.DECRYPT_MODE);
byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));
return new String(original);
}

private static Cipher initCipher(String secretKey, String salt, int mode) throws Exception {

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");

KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt.getBytes(), 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec skeySpec = new SecretKeySpec(tmp.getEncoded(), "AES");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(mode, skeySpec, new IvParameterSpec(new byte[16]));
return cipher;
}

public static void main(String[] args) throws Exception {
String secretKey = "Secret";
String fSalt = "tJHnN5b1i6wvXMwzYMRk";
String plainText = "England";

String cipherText = encrypt(secretKey, fSalt, plainText);
System.out.println("Cipher: " + cipherText);
// cipherText = "6peDTxE1xgLE4hTGg0PKTnuuhFC1Vftsd7NH9DF/7WM="; // Cipher from python
String dcrCipherText = decrypt(secretKey, fSalt, cipherText);
System.out.println(dcrCipherText);

}

Python代码(版本3.6)和Pycrypto V2.6

import base64
import hashlib
import os

from Crypto.Cipher import AES

BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)

# unpad = lambda s: s[:-ord(s[len(s) - 1:])]
unpad = lambda s: s[0:-s[-1]]

def get_private_key(secretKey, salt):
key = hashlib.pbkdf2_hmac('SHA256', secretKey.encode(), salt.encode(), 65536, 32)
return key


def encrypt(message, salt, secretKey):
private_key = get_private_key(secretKey, salt)
message = pad(message)
iv = os.urandom(BS) # 128-bit IV
cipher = AES.new(private_key, AES.MODE_CBC, iv, segment_size=256)
return base64.b64encode(iv + cipher.encrypt(message))


def decrypt(enc, salt, secretKey):
private_key = get_private_key(secretKey, salt)
enc = base64.b64decode(enc)
iv = enc[:BS]
cipher = AES.new(private_key, AES.MODE_CBC, iv, segment_size=256)
return unpad(cipher.decrypt(enc[BS:]))


secretKey = "Secret"
salt = "tJHnN5b1i6wvXMwzYMRk"
plainText = "England"
cipher = encrypt(plainText, salt, secretKey)
print("Cipher: " + bytes.decode(cipher))

# cipher = "0JrZdg9YBRshfTdr1d4zwQ==" # Cipher from java
decrypted = decrypt(cipher, salt, secretKey)
print("Decrypted " + bytes.decode(decrypted))

Java 解密输出:�U�����or���England当我通过 python 密码时,预期:EnglandPython解密输出:unpad = lambda s : s[0:-s[-1]]
IndexError: index out of range
,预期:England

我还浏览了堆栈上关于此问题的其他帖子,但是,由于他们使用了不同的模式,因此没有成功。

最佳答案

在 python 中,您将 iv(初始化 vector )存储在加密消息的前 16 个字节中。

在 Java 中,您没有做这样的事情 - 您传递的是一个空 IV,并且将包括前 16 个字节在内的整个消息视为密文。

您需要确保 Java 和 Python 匹配。

要么在两者中都不使用 IV,在这种情况下,您需要在 Python 中删除该部分。

或者您在两者中都使用 IV,在这种情况下,您需要更新 Java 代码以在加密时生成随机 IV,并将其添加到加密结果中。解密时,Java 代码需要将前 16 个字节作为 IV 并将其传递给 Cipher

关于Java-Python AES加密解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56572677/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com