加密和Python和机器人由AES算法解密 [英] Encrypt and Decrypt by AES algorithm in both python and android

查看:451
本文介绍了加密和Python和机器人由AES算法解密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对AES加密蟒蛇和Android code。当我在加密Android的文本,它解密的蟒蛇成功,但它不能在Android的一面解密。难道人有一个想法?

I have python and android code for AES encryption. When I encrypt a text in android, it decrypt on python successfully but it can’t decrypt in android side. Do anyone have an idea?

Python的code:

Python code :

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, message):
        message = self._pad(message)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return base64.b64encode(iv + cipher.encrypt(message)).decode('utf-8')

    def decrypt(self, enc):
        enc = base64.b64decode(enc)
        iv = enc[:AES.block_size]
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return self._unpad(cipher.decrypt(enc[AES.block_size:])).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:])]

Android的code:

Android Code:

import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Arrays;

import android.annotation.SuppressLint;
import android.location.Criteria;
import android.util.Base64;
import android.util.Log;

@SuppressLint("NewApi")
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 = "this is my key";
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;


Crypt()
{
    SecureRandom random = new SecureRandom();
    Crypt.ivBytes = new byte[16];
    random.nextBytes(Crypt.ivBytes); 
}

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

    return instance;
}

public String encrypt_string(final String plain) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, IOException
{
    return Base64.encodeToString(encrypt(plain.getBytes()), Base64.DEFAULT);
}

public String decrypt_string(final String plain) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, ClassNotFoundException, IOException
{
    byte[] encryptedBytes = decrypt(Base64.decode(plain, 0));
    return Base64.encodeToString( encryptedBytes, Base64.DEFAULT);
}



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, aesEncryptionAlgorithm);
    Cipher cipher = null;
    cipher = Cipher.getInstance(cipherTransformation);

    SecureRandom random = new SecureRandom();   
    Crypt.ivBytes = new byte[16];               
    random.nextBytes(Crypt.ivBytes);            

    cipher.init(Cipher.ENCRYPT_MODE, newKey, random);
//    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, aesEncryptionAlgorithm);
    Cipher cipher = Cipher.getInstance(cipherTransformation);
    cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec);
    byte[] res = cipher.doFinal(codB); 
    return  res;

}


}

当我跑这code在Android:

When I ran this code on android:

String str = "this is local test";
Log.i("myTag", "step1: " + str);
String a = aesCrypt.encrypt_string(str);
Log.i("myTag", "step2: " + a);
String b = aesCrypt.decrypt_string(a);
Log.i("myTag", "step3: " + b);

然后,我得到了这样的回答:

Then I got this answer:

step1: this is local test
step2: a0F8MhzkSpRlM+aM1MKzUdVCoXIE5y5hh4PRuwPfAhofKwLJjTUbBvmJzTsKJDqF
step3: dGhpcyBpcyBsb2NhbCB0ZXN0

不要任何人有想法为什么会发生?

Do anyone have idea why it happens ?

推荐答案

您正在解密编码后输出。

You're encoding the output after decryption.

public String decrypt_string(final String plain) throws ...
{
    byte[] encryptedBytes = decrypt(Base64.decode(plain, 0));
    return Base64.encodeToString( encryptedBytes, Base64.DEFAULT);
    //     ^--------------------| this 
}

如果你只加密可打印的数据,那么你可以安全地删除从上面的code中的 Base64.en codeToString 电话。要返回正确的类型,你可以做

If you only encrypt printable data then you can safely remove the Base64.encodeToString call from the above code. To return the correct type, you can do

return new String(encryptedBytes);

这篇关于加密和Python和机器人由AES算法解密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆