2017-01-06 194 views
0

我現在用的scotabb庫AESCryptor在我的Android項目AES加密,AES加密字符串IV

我真的需要使用AES字符串IV BCS我在SWIFT(IOS)等項目和web服務(C#)用字符串IV加密/解密256。

但在scotabb aesencriptor使用空白四。

是否可以將空白的IV(字節)更改爲16長度的字符串? 以及如何做到這一點?

這是我的課

public final class AEScrypt{ 

private static final String TAG = "AESCrypt"; 

//AESCrypt-ObjC uses CBC and PKCS7Padding 
private static final String AES_MODE = "AES/CBC/PKCS7Padding"; 
private static final String CHARSET = "UTF-8"; 

//AESCrypt-ObjC uses SHA-256 (and so a 256-bit key) 
private static final String HASH_ALGORITHM = "SHA-256"; 

//AESCrypt-ObjC uses blank IV (not the best security, but the aim here is compatibility) 
private static final byte[] ivBytes = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 
//togglable log option (please turn off in live!) 
public static boolean DEBUG_LOG_ENABLED = false; 



private static SecretKeySpec generateKey(final String password) throws NoSuchAlgorithmException, UnsupportedEncodingException { 
    final MessageDigest digest = MessageDigest.getInstance(HASH_ALGORITHM); 
    byte[] bytes = password.getBytes("UTF-8"); 
    digest.update(bytes, 0, bytes.length); 
    byte[] key = digest.digest(); 

    log("SHA-256 key ", key); 

    SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); 
    return secretKeySpec; 
} 


public static String encrypt(final String password, String message) 
     throws GeneralSecurityException { 

    try { 
     final SecretKeySpec key = generateKey(password); 

     log("message", message); 

     byte[] cipherText = encrypt(key, ivBytes, message.getBytes(CHARSET)); 

     //NO_WRAP is important as was getting \n at the end 
     String encoded = Base64.encodeToString(cipherText, Base64.NO_WRAP); 
     log("Base64.NO_WRAP", encoded); 
     return encoded; 
    } catch (UnsupportedEncodingException e) { 
     if (DEBUG_LOG_ENABLED) 
      Log.e(TAG, "UnsupportedEncodingException ", e); 
     throw new GeneralSecurityException(e); 
    } 
} 

public static byte[] encrypt(final SecretKeySpec key, final byte[] iv, final byte[] message) 
     throws GeneralSecurityException { 
    final Cipher cipher = Cipher.getInstance(AES_MODE); 
    IvParameterSpec ivSpec = new IvParameterSpec(iv); 
    cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); 
    byte[] cipherText = cipher.doFinal(message); 

    log("cipherText", cipherText); 

    return cipherText; 
} 



public static String decrypt(final String password, String base64EncodedCipherText) 
     throws GeneralSecurityException { 

    try { 
     final SecretKeySpec key = generateKey(password); 

     log("base64EncodedCipherText", base64EncodedCipherText); 
     byte[] decodedCipherText = Base64.decode(base64EncodedCipherText, Base64.NO_WRAP); 
     log("decodedCipherText", decodedCipherText); 

     byte[] decryptedBytes = decrypt(key, ivBytes, decodedCipherText); 

     log("decryptedBytes", decryptedBytes); 
     String message = new String(decryptedBytes, CHARSET); 
     log("message", message); 


     return message; 
    } catch (UnsupportedEncodingException e) { 
     if (DEBUG_LOG_ENABLED) 
      Log.e(TAG, "UnsupportedEncodingException ", e); 

     throw new GeneralSecurityException(e); 
    } 
} 


public static byte[] decrypt(final SecretKeySpec key, final byte[] iv, final byte[] decodedCipherText) 
     throws GeneralSecurityException { 
    final Cipher cipher = Cipher.getInstance(AES_MODE); 
    IvParameterSpec ivSpec = new IvParameterSpec(iv); 
    cipher.init(Cipher.DECRYPT_MODE, key, ivSpec); 
    byte[] decryptedBytes = cipher.doFinal(decodedCipherText); 

    log("decryptedBytes", decryptedBytes); 

    return decryptedBytes; 
} 


private static void log(String what, byte[] bytes) { 
    if (DEBUG_LOG_ENABLED) 
     Log.d(TAG, what + "[" + bytes.length + "] [" + bytesToHex(bytes) + "]"); 
} 

private static void log(String what, String value) { 
    if (DEBUG_LOG_ENABLED) 
     Log.d(TAG, what + "[" + value.length() + "] [" + value + "]"); 
} 

private static String bytesToHex(byte[] bytes) { 
    final char[] hexArray = {'0', '1', '2', '3', '4', '5', '6', '7', '8', 
      '9', 'A', 'B', 'C', 'D', 'E', 'F'}; 
    char[] hexChars = new char[bytes.length * 2]; 
    int v; 
    for (int j = 0; j < bytes.length; j++) { 
     v = bytes[j] & 0xFF; 
     hexChars[j * 2] = hexArray[v >>> 4]; 
     hexChars[j * 2 + 1] = hexArray[v & 0x0F]; 
    } 
    return new String(hexChars); 
} 

private AESCrypt() { 
} 

}

+0

**安全警告**:總之**不要使用'AESCryptor' **這樣的狗屎!當涉及到安全性時,不要複製代碼。 –

回答

1

您可以更改IV任何你想要的16字節的值。您可以看到靜態IV(不好的想法)在類級別定義爲0x00 * 16.您可以用另一個值(原始字節或解碼的十六進制或Base64值等)替換該字節數組。

您應該爲每個加密操作提供一個獨特且不可預測的IV,並將IV與密文一起傳遞以用於解密。 IV不需要被保護或加密,並且可以與密文一起清晰地傳播。