【问题标题】:AES encryption interoperability between python and androidpython和android之间的AES加密互操作性
【发布时间】:2015-01-27 13:10:22
【问题描述】:

我在我的 python (Django) 服务器上获取了此代码,以加密我的消息到 Java 客户端 (Android)。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import base64
import hashlib
from Crypto import Random
from Crypto.Cipher import AES

class AESCipher:

    def __init__(self, key):
        self.bs = 16
        self.key = hashlib.sha256(key.encode()).digest()

    def encrypt(self, raw):
        raw = self._pad(raw)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        cTxt = (iv + cipher.encrypt(raw))
        return base64.b64encode(cTxt)

    def decrypt(self, enc):
        enc = base64.b64decode(enc)
        iv = enc[:AES.block_size]
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        dPadded = cipher.decrypt(enc[AES.block_size:])
        return self._unpad(dPadded).decode('utf-8')

    def _pad(self, s):
        return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs)

    @staticmethod
    def _unpad(s):
        return s[:-ord(s[len(s)-1:])]

我是这样用的:

    phrase = "Prueba de Encryptado"
    key = "e8ffc7e56311679f12b6fc91aa77a5eb"

    cryp = AESCipher(key)
    eTxt = cryp.encrypt(phrase)
    dTxt = cryp.decrypt(eTxt)

在我的 Java-Android 客户端上;我尝试用这个类解密:

 public class Crypt {

private static final String tag = Crypt.class.getSimpleName();

private static final String characterEncoding = "UTF-8";
private static final String cipherTransformation = "AES/CBC/PKCS5Padding";
private static final String aesEncryptionAlgorithm = "AES";
private static final String key = "e8ffc7e56311679f12b6fc91aa77a5eb";
private static byte[] ivBytes = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
private static byte[] keyBytes;

private static Crypt instance = null;


private Crypt(){}



public static Crypt getInstance() {
    if(instance == null){
        instance = new Crypt();
    }

    return instance;
}



public   byte[] encrypt(   byte[] mes)
        throws NoSuchAlgorithmException,
        NoSuchPaddingException,
        InvalidKeyException,
        InvalidAlgorithmParameterException,
        IllegalBlockSizeException,
        BadPaddingException, IOException {

    keyBytes = key.getBytes("UTF-8");
    Log.d(tag,"Long KEY: "+keyBytes.length);
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    md.update(keyBytes);
    keyBytes = md.digest();

    Log.d(tag,"Long KEY: "+keyBytes.length);

    AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
    SecretKeySpec newKey = new SecretKeySpec(keyBytes, "AES");
    Cipher cipher = null;
    cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, newKey, ivSpec);

    byte[] destination = new byte[ivBytes.length + mes.length];
    System.arraycopy(ivBytes, 0, destination, 0, ivBytes.length);
    System.arraycopy(mes, 0, destination, ivBytes.length, mes.length);
    return  cipher.doFinal(destination);

}

public   byte[] decrypt(   byte[] bytes)
        throws NoSuchAlgorithmException,
        NoSuchPaddingException,
        InvalidKeyException,
        InvalidAlgorithmParameterException,
        IllegalBlockSizeException,
        BadPaddingException, IOException, ClassNotFoundException {

    keyBytes = key.getBytes("UTF-8");
    Log.d(tag,"Long KEY: "+keyBytes.length);
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    md.update(keyBytes);
    keyBytes = md.digest();
    Log.d(tag,"Long KEY: "+keyBytes.length);

    byte[] ivB = Arrays.copyOfRange(bytes,0,16);
    Log.d(tag, "IV: "+new String(ivB));
    byte[] codB = Arrays.copyOfRange(bytes,16,bytes.length);


    AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivB);
    SecretKeySpec newKey = new SecretKeySpec(keyBytes, "AES");
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec);
    return  cipher.doFinal(codB);

}

}

但我不能像在我的 python 代码中那样解密;我不知道为什么,但每次我尝试;这些是我的例外:

javax.crypto.BadPaddingException: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
at com.android.org.conscrypt.NativeCrypto.EVP_CipherFinal_ex(Native Method)
at com.android.org.conscrypt.OpenSSLCipher.doFinalInternal(OpenSSLCipher.java:430)
at com.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:466)
at javax.crypto.Cipher.doFinal(Cipher.java:1340)
at net.kaimanden.testcrypt.Crypt.doDecryption(Crypt.java:75)

【问题讨论】:

  • BadPaddingException 上的 Java 文档:“当输入数据需要特定的填充机制但未正确填充数据时,会引发此异常。”

标签: java android python encryption aes


【解决方案1】:

您忘记在 Java 代码中派生密钥。在 python 代码中,您使用密码 (key) 通过 SHA-256 导出实际的 256 位密钥。

另一方面,在 Java 中,您直接使用 key = "HolaQueTal",它甚至太短而无法用作正确的键,甚至与您的 python 示例中的键不同。 MessageDigest 类支持 SHA-256。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-07
    • 2022-06-13
    • 2011-02-01
    • 1970-01-01
    • 2019-08-03
    • 2011-03-16
    • 2013-06-08
    • 1970-01-01
    相关资源
    最近更新 更多