2015-05-30 67 views
-2

我正在使用"AES256/PKCS5Padding/ECB"加密來加密文本以發送服務器。以下Android代碼運行良好,以便在NodeJS服務器中正確解密加密數據。Objective C加密代碼不能像Android AES 256,md5加密

public static String encryptAES_Java_Node(String content, String key) { 
  
              byte[] input; 
              String query = null; 
              try { 
                     input = content.getBytes("utf-8"); 
  
                     MessageDigest md = MessageDigest.getInstance("MD5"); 
                     byte[] thedigest = md.digest(key.getBytes("UTF-8")); 
                     SecretKeySpec skc = new SecretKeySpec(thedigest, 
                                  "AES/ECB/PKCS5Padding"); 
                     Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); 
                     cipher.init(Cipher.ENCRYPT_MODE, skc); 
  
                     byte[] cipherText = newbyte[cipher.getOutputSize(input.length)]; 
                     int ctLength = cipher.update(input, 0, input.length, cipherText, 0); 
                     ctLength += cipher.doFinal(cipherText, ctLength); 
  
                     query = Base64.encodeToString(cipherText, Base64.DEFAULT); 
                     
              } catch (UnsupportedEncodingException e) { 
                     // TODO Auto-generated catch block 
                     e.printStackTrace(); 
              } catch (NoSuchAlgorithmException e) { 
                     // TODO Auto-generated catch block 
                     e.printStackTrace(); 
              } catch (NoSuchPaddingException e) { 
                     // TODO Auto-generated catch block 
                     e.printStackTrace(); 
              } catch (InvalidKeyException e) { 
                     // TODO Auto-generated catch block 
                     e.printStackTrace(); 
              } catch (IllegalBlockSizeException e) { 
                     // TODO Auto-generated catch block 
                     e.printStackTrace(); 
              } catch (ShortBufferException e) { 
                     // TODO Auto-generated catch block 
                     e.printStackTrace(); 
              } catch (BadPaddingException e) { 
                     // TODO Auto-generated catch block 
                     e.printStackTrace(); 
              } 
              return query; 
  
       } 

這是我在ObjC

(NSString *)encryptText:(NSString *)rawText withKey:(NSString *)key { 
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise 
    char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused) 
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding) 


    NSData *rawData = [rawText dataUsingEncoding:NSUTF8StringEncoding]; 

    //Convert to hash 
    NSString *md5Key = [self MD5String:key]; 

    // fetch key data 
    [md5Key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; 

    NSUInteger dataLength = [rawData length]; 

    //See the doc: For block ciphers, the output size will always be less than or 
    //equal to the input size plus the size of one block. 
    //That's why we need to add the size of one block here 
    size_t bufferSize = dataLength + kCCBlockSizeAES128; 
    void *buffer = malloc(bufferSize); 

    size_t numBytesEncrypted = 0; 
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding + kCCOptionECBMode, 
              keyPtr, kCCKeySizeAES256, 
              NULL /* initialization vector (optional) */, 
              [rawData bytes], dataLength, /* input */ 
              buffer, bufferSize, /* output */ 
              &numBytesEncrypted); 
    if (cryptStatus == kCCSuccess) { 
     //the returned NSData takes ownership of the buffer and will free it on deallocation 
     NSData *tempData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; 
     NSString* encrypted64 = [tempData base64EncodedStringWithOptions:0];//Even i have tried base 64 encding with other options available 
     return encrypted64; 
    } 

    free(buffer); //free the buffer; 
    return nil; 
} 

代碼我是不是犯了一個錯誤,而轉換鍵,MD5作爲android系統中做了什麼?

在NodeJS服務中添加用於解密的代碼以供參考。

var decipher = crypto.createDecipher('aes-128-ecb', encryption_key); 

      chunks = [] 
      chunks.push(decipher.update(new Buffer(fullBuffer, "base64").toString("binary"))); 
      chunks.push(decipher.final('binary')); 
      var txt = chunks.join(""); 
      txt = new Buffer(txt, "binary").toString("utf-8"); 

// where encryption_key = key, fullBuffer is the input and txt is output 
+0

使用Android,您將MD5作爲字節數組獲取。使用iOS,您將獲得MD5(最有可能)作爲其字符串表示形式。 – zneak

+1

您可能想要考慮使用加密網絡協議,而不是自己使用加密基元。密碼學既重要又難以正確。 – zneak

+2

「不工作」不是錯誤描述。 SO不是在線調試器;請顯示你曾經嘗試過/你卡在哪裏。 –

回答

0

MD5產生一個16字節的結果。

Java將看到此密鑰並使用使用16字節密鑰的AES128。最好使用以下代碼明確指定Java版本中的密鑰大小:"AES/ECB/NoPadding (128)"

iOS版本明確指定使用32字節密鑰的AES256,並且將null填充16字節至32字節。

在iOS版本中將加密更改爲AES16:kCCKeySizeAES128

有安全問題:

  1. 使用MD5創建密鑰字符串中是不安全的,目前的做法是使用一個密鑰導出函數,例如PBKDF2在迭代次數和隨機鹽是預先傳遞給加密數據。

  2. ECB模式不是非常安全,使用CBC模式和隨機的IV會好得多,並且預先將iv加密到加密的數據中。

    但是如果安全性不重要MD5和ECB都可以。

+0

我的邏輯有錯誤嗎?如果你能顯示一些代碼,這樣我就可以得到相同的輸出結果,這將對你有所幫助。 – Gabby

+0

空填充「123456」不會產生「12345600000000000000000000000000」,那些「0」字符是數字零:0x30,而不是0x00。 – zaph

+0

你的意思是「鹽」:鹽是「12345600000000000000000000000000」。加密密鑰?關鍵和鹽有區別。如果在「12345」中使用密鑰,Java很可能會填充到16字節並使用AES128。 iOS顯式指定了AES256,它是一個32字節的密鑰。 – zaph