2015-03-12 73 views
7

Tôi có mã python và android cho mã hóa AES. Khi tôi mã hóa một văn bản trong android, nó giải mã trên python thành công nhưng nó không thể giải mã ở phía bên android. Có ai có ý tưởng không? đangMã hóa và giải mã bằng thuật toán AES trong cả python và android

Python:

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:

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; 

} 


} 

Khi tôi chạy mã này trên 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); 

Sau đó, tôi nhận được câu trả lời này:

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

Có ai có ý tưởng tại sao điều đó xảy ra không?

+0

Tôi đang sử dụng mã Python trên, khi tôi mã hóa String trong Android, tôi không thể giải mã nó trong Python (V3.5.2) và ngược lại. – Janmejoy

+0

@Janmejoy. vui lòng thay đổi mã dựa trên câu trả lời sau đây của "Artjom B". Tôi đã làm trong python 3.4 và nó vẫn hoạt động tốt. xem bình luận của tôi về câu trả lời quá – irmorteza

Trả lời

4

Bạn đang mã hóa đầu ra sau khi giải mã.

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

Nếu bạn chỉ mã hóa dữ liệu có thể in thì bạn có thể an toàn xóa cuộc gọi Base64.encodeToString khỏi mã ở trên. Để trở về đúng loại, bạn có thể làm

return new String(encryptedBytes); 
+0

Cảm ơn bạn rất nhiều. bạn đúng . Tôi đã thay đổi dòng cuối cùng thành {return new String (encryptedBytes); }. và nó hoạt động hoàn hảo. Đôi khi chúng ta cần nghỉ ngơi sau một thời gian dài lập trình;) – irmorteza

+0

Có, điều đó xảy ra. Tôi đã thêm đề xuất của bạn vào câu trả lời của tôi. –

Các vấn đề liên quan