加密和Python和机器人由AES算法解密 [英] Encrypt and Decrypt by AES algorithm in both python and android
问题描述
我对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屋!