在Swift中,我得到了与实际结果不同的结果。调试时,我注意到Java默认使用有符号整数。所以我采用了同样的方式,在这种情况下,我能够验证两个应用程序(Java和Swift)中的derivedKey是相同的。
但在创建keyData和ivData时,它丢失了有符号数据。不确定是否会导致问题。
我尝试了在AES Encryption .net to swift中解释的以下代码。
func decrypt(encryptedText: String, keys :String) -> String{
let encryptedData = encryptedText.data(using: .utf16LittleEndian)
let derivedKey = generateDerivedKey(keyString: keys)
let key = Array(derivedKey[0..<32])
let iv = Array(derivedKey[32..<48])
let keyData = Data(bytes: key, count: key.count)
let ivData = Data(bytes: iv, count: iv.count)
let decryptedData = testDeCrypt(data: encryptedData!, keyData: keyData, ivData: ivData, operation: kCCDecrypt)
return String(bytes: decryptedData, encoding: .unicode)!
}
func generateDerivedKey(keyString :String) -> [Int8] {
let salt: [UInt8] = [0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76]
var key = [UInt8](repeating: 0, count: 48)
CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2), keyString, keyString.utf8.count, salt, salt.count, CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA1), 1000, &key, 48)
let derivedKey : [Int8] = key.map {Int8(bitPattern: $0)}
return derivedKey
}
func testDeCrypt(data: Data, keyData: Data, ivData: Data, operation: Int) -> Data {
assert(keyData.count == Int(kCCKeySizeAES128) || keyData.count == Int(kCCKeySizeAES192) || keyData.count == Int(kCCKeySizeAES256))
var decryptedData = Data(count: data.count)
var num_bytes_decrypted: size_t = 0
let operation = CCOperation(operation)
let algoritm = CCAlgorithm(kCCAlgorithmAES)
let options = CCOptions(kCCOptionPKCS7Padding)
let decryptedDataCount = decryptedData.count
let cryptoStatus = keyData.withUnsafeBytes {keyDataBytes in
ivData.withUnsafeBytes {ivDataBytes in
data.withUnsafeBytes {dataBytes in
decryptedData.withUnsafeMutableBytes {decryptedDataBytes in
CCCrypt(operation, algoritm, options, keyDataBytes, keyData.count, ivDataBytes, dataBytes, data.count, decryptedDataBytes, decryptedDataCount, &num_bytes_decrypted)
}
}
}
}
if cryptoStatus == CCCryptorStatus(kCCSuccess) {
decryptedData.count = num_bytes_decrypted
return decryptedData
} else {
return Data()
}
}
Java 代码
public static String aesDecrypt(String text, String key) {
byte[] decValue = null;
try {
byte[] salt = new byte[] { 0x49, 0x76, 0x61, 0x6E, 0x20, 0x4D,
0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 };
SecretKeyFactory factory = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec pbeKeySpec = new PBEKeySpec(key.toCharArray(), salt,
1000, 384);
Key secretKey = factory.generateSecret(pbeKeySpec);
byte[] keys = new byte[32];
byte[] iv = new byte[16];
System.arraycopy(secretKey.getEncoded(), 0, keys, 0, 32);
System.arraycopy(secretKey.getEncoded(), 32, iv, 0, 16);
SecretKeySpec secretSpec = new SecretKeySpec(keys, "AES");
AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
try {
cipher.init(Cipher.DECRYPT_MODE, secretSpec, ivSpec);
} catch (InvalidKeyException e) {
} catch (InvalidAlgorithmParameterException e) {
}
org.apache.commons.codec.binary.Base64 decoder = new org.apache.commons.codec.binary.Base64();
byte[] decodedValue = decoder.decode(text.getBytes());
decValue = cipher.doFinal(decodedValue);
} catch (Exception e) {
}
if (decValue != null) {
return new String(decValue, Charset.forName("UTF_16LE"));
} else {
return null;
}
}
测试数据 密钥:"ThisIsATestPassword444Encryption" 文本:"TestStringToEncrypt"
Java输出 编码后的密文:[97,47,77,79,118,111,79,70,47,87,90,67,81,98,51,74,83,88,97,68,84,105,72,71,67,121,122,86,81,116,106,104,117,78,108,118,49,48,65,77,69,53,114,43,120,104,89,120,50,98,80,66,50,77,87,80,103,110,117,118,118,97,78,106]
加密后的文本:a/MOvoOF/WZCQb3JSXaDTiHGCyzVQtjhuNlv10AME5r+xhYx2bPB2MWPgnuvvaNj
解密文本.getBytes:[97,47,77,79,118,111,79,70,47,87,90,67,81,98,51,74,83,88,97,68,84,105,72,71,67,121,122,86,81,116,106,104,117,78,108,118,49,48,65,77,69,53,114,43,120,104,89,120,50,98,80,66,50,77,87,80,103,110,117,118,118,97,78,106]
解码解密文本:[107,-13,14,-66,-125,-123,-3,102,66,65,-67,-55,73,118,-125,78,33,-58,11,44,-43,66,-40,-31,-72,-39,111,-41,64,12,19,-102,-2,-58,22,49,-39,-77,-63,-40,-59,-113,-126,123,-81,-67,-93,99]
Swift输出: 加密文本:a/MOvoOF/WZCQb3JSXaDTiHGCyzVQtjhuNlv10AME5r+xhYx2bPB2MWPgnuvvaNj
解密文本:۽瑒왿᪰߆牷ྐྵ䐫徺ꋴ鐧ݐ斑ﷃ翴㦦જ㤉ꄕ䞴櫘勐鼍ᐏ┓ീ學䥏㿖칵鬥솽ᢼ铡鴷⤃ꗞ䛂䋗쿠蒻⯨䍊䂷篥럟⤫俷違둘๔Ꞵ‵
Swift和Java加密匹配。
非常感谢您的帮助。
text.getBytes()
是什么? - OOPerPBEKeySpec
的细节,问题可能不是我上次评论中提到的那个问题。 - OOPer