2015-03-12 14 views
7

Mam kod Pythona i Android do szyfrowania AES. Kiedy zaszyfruję tekst w Androidzie, odszyfrowuje on na komputerze Pythona, ale nie może odszyfrować go po stronie Androida. Czy ktoś ma pomysł? KodSzyfruj i odszyfruj według algorytmu AES zarówno w pythonie, jak i Androidzie

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 Kod:

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; 

} 


} 

Kiedy wpadłem ten kod na Androidzie:

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); 

Potem dostałem taką odpowiedź:

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

Czy ktoś ma pomysł, dlaczego tak się dzieje?

+0

Używam powyższy kod Pythona, kiedy zaszyfrować ciąg w Androidzie, nie jestem w stanie odszyfrować w Pythonie (V3.5.2) i vice versa. – Janmejoy

+0

@Janmejoy. zmień podstawę kodu po odpowiedzi "Artjom B". Zrobiłem w Pythonie 3.4 i nadal działa dobrze. zobacz także mój komentarz na temat odpowiedzi – irmorteza

Odpowiedz

4

Kodujesz dane wyjściowe po odszyfrowaniu.

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

Jeśli tylko szyfrowania danych do druku a następnie można bezpiecznie usunąć Base64.encodeToString połączenia z powyższego kodu. Aby przywrócić prawidłowy typ, można zrobić

return new String(encryptedBytes); 
+0

Dziękuję bardzo. masz rację . Zmieniłem ostatnią linię na {return new String (encryptedBytes); }. i działa idealnie. Czasami potrzebujemy odpoczynku po długim programowaniu;) – irmorteza

+0

Tak, to się dzieje. Dodałem twoją sugestię do mojej odpowiedzi. –

Powiązane problemy