【问题标题】:How can I convert this Java encryption code to python如何将此Java加密代码转换为python
【发布时间】:2021-11-03 16:13:52
【问题描述】:

我试图将java 代码转换为python。试图为此目的使用pycryptodome 库。这是java 代码:

try {
    String data= "shouldEncryptDATA";
    String bas64ed= "";
    int len12 = Integer.parseInt("12");
    byte[] randomparam= new byte[len12];
    new SecureRandom().nextBytes(randomparam);
    SecretKeySpec secretKeySpec= new SecretKeySpec("1f1f7892GKG38815".getBytes(), "AES");
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
    cipher.init(1, secretKeySpec, new GCMParameterSpec(Integer.parseInt("16") * 8, randomparam)); 
    byte[] bytedata= cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
    byte[] newbytearray= new byte[bytedata.length + len12];
    System.arraycopy(randomparam, 0, newbytearray, 0, len12); 
    System.arraycopy(bytedata, 0, newbytearray, len12, bytedata.length);
    bas64ed= Base64.getEncoder().encodeToString(newbytearray);
    System.out.println("bas64ed: "+bas64ed);
            
    System.out.println(URLEncoder.encode(bas64ed, "UTF-8"));
          
} catch (Exception unused_ex) {
    System.out.println();
    System.out.println("ERROR: " + unused_ex);
}

到目前为止,我尝试python 代码下方模仿java 代码:

import base64
from Crypto.Cipher import AES
import urllib.parse
from Crypto.Random import get_random_bytes

data= "shouldEncryptDATA"

key = b '1f1f7892GKG38815' 

len12 = 12
v1 = bytearray(len12)
                                         
cipher = AES.new(key, AES.MODE_GCM, nonce=get_random_bytes(12) ) 
ciphertext, tag = cipher.encrypt_and_digest(data.encode("utf8"))
base64ed = ""
for x in cipher.nonce, ciphertext, tag:
        base64ed += base64.b64encode(x).decode('utf-8')
urlencoded = urllib.parse.quote_plus(base64ed+"\n")

print(urlencoded )

上面的python 代码生成一个output,但问题是当我将输出提供给decryption 代码时,我得到了MAC check Failed。所以我意识到我在python 代码中的实现有点问题,因为当Java 代码的输出传递给decryption 代码时,它可以工作并解密数据。那么如何正确地将Java 加密代码转换为Python?使用Pycryptodome 或任何其他合适的库。

【问题讨论】:

    标签: java python encryption aes-gcm pycryptodome


    【解决方案1】:

    Python代码中的Bug在拼接中,一定是:

    base64ed = base64.b64encode(cipher.nonce + ciphertext + tag).decode('utf-8')
    

    在此修复后,如果您将两个代码的密文与相同的输入数据(尤其是具有相同的 IV)进行比较,它们是相同的。

    【讨论】:

    • @hanan - 两种代码为每种加密提供不同的密文。这是由于随机 IV 造成的,并且出于安全原因是必要的。因此,如果您想比较 Java 和 Python 代码的密文,您必须使用相同的 IV(当然,仅用于测试)!验证的另一种可能性是解密。
    • 虽然您共享的代码是正确的,但是当我将java 代码的输出提供给server 时,它工作正常,但python 代码的输出它返回Invalid Input Data。我的意思是IV 有问题吗?它是使用new GCMParameterSpec(Integer.parseInt("16") * 8, randomparam) 生成的java 端?正确的?但是在python中我不知道我该怎么做? get_randombytes(12) 只是猜测和尝试。
    • 这两行都生成随机的(因此当然不同)12 字节的 IV,这是非常正确的! IV 与密文连接,以便在解密期间可用。此外,在我的机器上,当应用相同的明文、相同的密钥,尤其是 相同的 IV 时,Java 和 Python 代码会生成 相同 密文。如果对你来说不同,你应该发布一个例子:两个代码的明文、密钥、IV和密文。
    猜你喜欢
    • 1970-01-01
    • 2019-11-19
    • 2018-06-24
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    • 2017-05-10
    • 2014-03-24
    • 1970-01-01
    相关资源
    最近更新 更多