2015-03-12 26 views
7

Ho codice Python e Android per la crittografia AES. Quando crittografo un testo in Android, decodifica su Python con successo ma non può decifrare nel lato Android. Qualcuno ha un'idea? CodiceEncrypt and Decrypt by AES algorithm in python e 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:])] 

Codice Android:

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; 

} 


} 

Quando ho eseguito questo codice su 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); 

Poi ho avuto questa risposta:

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

Qualcuno ha idea del perché succede?

+0

Sto usando il codice Python sopra, quando ho crittografare la stringa in Android, io non sono in grado di decifrare in Python (v3.5.2) e viceversa. – Janmejoy

+0

@Janmejoy. per favore cambia codice base sulla seguente risposta di "Artjom B". Ho fatto in Python 3.4 e funziona ancora bene. guarda anche il mio commento sulla risposta – irmorteza

risposta

4

Stai codificando l'output dopo la decrittografia.

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

Se crittografare solo i dati stampabili allora si può rimuovere in sicurezza il Base64.encodeToString chiamata dal codice di cui sopra. Per restituire il tipo corretto, si può fare

return new String(encryptedBytes); 
+0

Grazie mille. hai ragione . Ho cambiato l'ultima riga in {return new String (encryptedBytes); }. e funziona perfettamente. A volte abbiamo bisogno di riposare dopo una lunga programmazione;) – irmorteza

+0

Sì, succede. Ho aggiunto il tuo suggerimento alla mia risposta. –