2015-03-12 12 views
7

Ich habe Python und Android-Code für AES-Verschlüsselung. Wenn ich einen Text in Android verschlüssle, entschlüsselt es auf Python erfolgreich, aber es kann nicht in Android-Seite entschlüsseln. Hat jemand eine Idee?Verschlüsseln und Entschlüsseln durch AES-Algorithmus in Python und Android

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:

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; 

} 


} 

Wenn ich diesen Code auf Android lief:

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

Dann bekam ich diese Antwort:

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

Hat jemand eine Idee, warum es passiert?

+0

ich den oben Python-Code verwende, wenn ich den String in Android verschlüsseln, bin ich nicht in der Lage es in Python zu entschlüsseln (V3.5.2) und umgekehrt. – Janmejoy

+0

@Janmejoy. Bitte ändern Sie die Code-Basis auf folgende Antwort von "Artjom B". Ich habe in Python 3.4 und es funktioniert immer noch gut. siehe mein Kommentar auf Antwort zu – irmorteza

Antwort

4

Sie codieren die Ausgabe nach der Entschlüsselung.

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

Wenn Sie verschlüsseln nur druckbare Daten, dann können Sie sicher den Base64.encodeToString Anruf aus dem obigen Code entfernen. Um die richtige Art zurückkehren, können Sie tun

return new String(encryptedBytes); 
+0

Vielen Dank. Du hast recht . Ich habe die letzte Zeile in {return new String (encryptedBytes) geändert; }. und es funktioniert perfekt. Manchmal brauchen wir ein paar Ruhe nach einer langen Programmierzeit;) – irmorteza

+0

Ja, es passiert. Ich habe Ihren Vorschlag zu meiner Antwort hinzugefügt. –

Verwandte Themen