2012-06-28 77 views
0

我正在編寫一個使用AES(ECB)模式加密和解密數據的應用程序。 黑莓代碼的加密數據通過php代碼成功解密。 但問題是,當我從PHP加密文本我不能解密它與黑莓代碼..即使我沒有得到任何異常。無法解密AES的黑莓中的php代碼密文

這裏是我的代碼來加密和解密文本。

public static byte[] encrypt(byte[] keyData, byte[] data) 
throws CryptoException, IOException 
{ 
    // Create the AES key to use for encrypting the data. 
    // This will create an AES key using as much of the keyData 
    // as possible. 
    AESKey key = new AESKey(keyData); 

    // Now, we want to encrypt the data. 
    // First, create the encryptor engine that we use for the actual 
    // encrypting of the data. 
    AESEncryptorEngine engine = new AESEncryptorEngine(key); 

    // Since we cannot guarantee that the data will be of an equal block 
    // length we want to use a padding engine (PKCS5 in this case). 
    PKCS5FormatterEngine fengine = new PKCS5FormatterEngine(engine); 

    // Create a BlockEncryptor to hide the engine details away. 
    ByteArrayOutputStream output = new ByteArrayOutputStream(); 
    BlockEncryptor encryptor = new BlockEncryptor(fengine, output); 



    encryptor.write(data); 

    encryptor.close(); 
    output.close(); 


    return output.toByteArray(); 
} 
public static String AESDecryption(byte[] keyData,byte[] cipherText, int dataLength) throws CryptoException, IOException { 

    // Create the input stream based on the ciphertext 
    ByteArrayInputStream in = new ByteArrayInputStream(cipherText, 0, dataLength); 

    // Now create the block decryptor and pass in a new instance 
    // of an AES decryptor engine with the specified block length 
    BlockDecryptor cryptoStream = new BlockDecryptor(new AESDecryptorEngine(new AESKey(keyData)), in); 

    byte[] T= new byte[dataLength]; 
    // Read the decrypted text from the AES decryptor stream and 
    // return the actual length read 

    int length= cryptoStream.read(T); 
    String str= new String(T); 


    return str; 
} 

由於事先..

回答

3

這裏是接受密鑰和加密的數據(在字節數組的形式)的方法和在字節數組的形式返回解密後的數據:

public static byte[] decrypt(byte[] keyData, byte[] ciphertext) 
     throws CryptoException, IOException { 

    // First, create the AESKey again. 
    AESKey key = new AESKey(keyData); 

    // Now, create the decryptor engine. 
    AESDecryptorEngine engine = new AESDecryptorEngine(key); 
    // Since we cannot guarantee that the data will be of an equal block length 
    // we want to use a padding engine (PKCS5 in this case). 
    PKCS5UnformatterEngine uengine = new PKCS5UnformatterEngine(engine); 

    // Create the BlockDecryptor to hide the decryption details away. 
    ByteArrayInputStream input = new ByteArrayInputStream(ciphertext); 
    BlockDecryptor decryptor = new BlockDecryptor(uengine, input); 

    // Now, read in the data. 
    byte[] temp = new byte[100]; 
    DataBuffer buffer = new DataBuffer(); 

    for (;;) { 
     int bytesRead = decryptor.read(temp); 
     buffer.write(temp, 0, bytesRead); 

     if (bytesRead < 100) { 
      // We ran out of data. 
      break; 
     } 
    } 

    byte[] plaintext = buffer.getArray(); 

    return plaintext; 
} 

注意加密/解密不能直接對字符串進行操作。它只適用於字節數組。因此,作爲最後的操作,您需要使用String(byte[] bytes)String(byte[] bytes, String enc)構造函數將解密的字節數組轉換爲字符串。如果您的字符串使用除「ISO-8859-1」編碼之外的其他編碼(這是BlackBerry的默認編碼)編碼,則第二個構造函數可能很有用。

UPDATE:

事實證明你沒有在服務器端使用PKCS5填充和你加密的字節數據轉換爲十六進制字符串,那麼解決的代碼是:

// this is to convert HEX to bytes 
public static byte[] convertHexToBytes(String s) { 
    int len = s.length(); 
    byte[] data = new byte[len/2]; 
    for (int i = 0; i < len; i += 2) { 
     data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) 
          + Character.digit(s.charAt(i+1), 16)); 
    } 
    return data; 
} 

// this is the same as initial version, but we don't handle PKCS5 padding here 
public static byte[] decrypt(byte[] keyData, byte[] ciphertext) 
     throws CryptoException, IOException { 

    // First, create the AESKey again. 
    AESKey key = new AESKey(keyData); 

    // Now, create the decryptor engine. 
    AESDecryptorEngine engine = new AESDecryptorEngine(key); 

    // Create the BlockDecryptor to hide the decryption details away. 
    ByteArrayInputStream input = new ByteArrayInputStream(ciphertext); 
    BlockDecryptor decryptor = new BlockDecryptor(engine, input); 

    // Now, read in the data. 
    byte[] temp = new byte[100]; 
    DataBuffer buffer = new DataBuffer(); 

    for (;;) { 
     int bytesRead = decryptor.read(temp); 
     buffer.write(temp, 0, bytesRead); 

     if (bytesRead < 100) { 
      // We ran out of data. 
      break; 
     } 
    } 

    byte[] plaintext = buffer.getArray(); 

    return plaintext; 
} 

// and finally :) 
String key =  "123456789"; 
String encrypted = "48b983c4f1575280d244b74cf689efe5"; 

byte[] keyBytes = key.getBytes(); 
byte[] encryptedBytes = convertHexToBytes(encrypted); 

// displays "nirav bhandari" 
Dialog.inform(new String(decrypt(keyBytes, encryptedBytes))); 
+0

我還用你上面提到的相同的代碼... BT也值得一少...加密文本從PHP犯規獲得decryptd ... 這裏是我的密碼 48b983c4f1575280d244b74cf689efe5 表示,key是123456789試着解密....你無法解密它我的朋友.... –

+0

主要問題是什麼是48b983c4f1575280d244b74cf689efe5?這是你在BB方面得到的字符串嗎?它看起來像一個HASH ..或者它是一個Base64編碼的字符串?在你將它發送給BB之前,你在加密的字節數組中使用PHP做什麼? –

+0

夥計它是六進制代碼...即時通訊將其轉換爲字節,然後使用上述函數解密它...但沒有得到輸出。即使我沒有得到無效的純文本...異常還說「沒有堆棧跟蹤」..所以不知道什麼是問題..如果我把hexacode比48b983c4f1575280d244b74cf689efe5然後我的BB代碼解密它,並給我無效的純文本..所以不知道最新的問題是 –

1

當您調用解密函數時,如何將密文轉換爲字節[]?

+0

我問Nirav Bhandari「你在PHP上使用加密字節數組做什麼,然後將它發送給BB?」,但是我們仍然不在同一頁上。:) –

+0

在服務器端....im執行followingoperatio on純文本 首先使用rijandl 128位AES算法將純文本轉換爲密碼....使用以下代碼 $ cypher = mcrypt_module_open(MCRYPT_RIJNDAEL_128,'',MCRYPT_MODE_ECB,'');使用缺省PHP函數 $加密= mcrypt_generic($暗號,$數據) 然後即時加密數據; //(mdecrypt_generic($暗號,$數據); 然後將其轉換爲六和返回.. ,即時通訊轉換後二進制密碼到hexa,並回到我的clienyt。這就是它.. –