.Net代码:
public string AESEncrypt(string clearText,string key)
{
string EncryptionKey = key; // "MAKV2SPBNI99212";
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
int iterations = 1024;
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }, iterations);
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray());
}
}
return clearText;
}Swift代码:
// "MAKV2SPBNI99212" Key
func AESEncryptedString( withKey key : String) -> String? {
let salt : Array <UInt8> = [0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76]
let saltData = NSData(bytes: salt, length: 13)
let myPassData : NSData = key.data(using: String.Encoding.utf8)! as NSData
var key = [UInt8](repeating: 0, count: 48)
var initialVector = [UInt8](repeating: 0, count: 16)
let ptrData = myPassData.bytes.assumingMemoryBound(to: Int8.self)
let ptrSalt = saltData.bytes.assumingMemoryBound(to: UInt8.self)
let keyPtr = UnsafeMutablePointer<UInt8>(mutating: key)
CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2), ptrData, myPassData.length, ptrSalt, saltData.length, CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA1), 1024, keyPtr, 48)
initialVector = Array(key[32..<48])
key = Array(key[0..<32])
let keyD = Data(bytes: key)
let ivD = Data(bytes:initialVector)
let rawData = self.data(using: String.Encoding.unicode)
let encryptedData = testCrypt(data:rawData!, keyData:keyD, ivData:ivD, operation:kCCEncrypt)
let decryptedData = testDeCrypt(data:encryptedData, keyData:keyD, ivData:ivD, operation:kCCDecrypt)
let decrypted = String(bytes:decryptedData, encoding:String.Encoding.utf16)!
print("Encrypted Data: \(encryptedData.base64EncodedString()) \n with count: \(encryptedData.base64EncodedString().characters.count)")
print("Decrypted: \(decrypted)")
let encryptedString = encryptedData.base64EncodedString()
return encryptedString
}
func testCrypt(data:Data, keyData:Data, ivData:Data, operation:Int) -> Data {
let buffer_size : size_t = (data as NSData).length + kCCBlockSizeAES128
let buffer = UnsafeMutablePointer<NSData>.allocate(capacity: buffer_size)
var num_bytes_encrypted : size_t = 0
let operation = CCOperation(operation)
let algoritm = CCAlgorithm(kCCAlgorithmAES)
let options = CCOptions( kCCOptionPKCS7Padding)
let keyLength = size_t(kCCKeySizeAES256)
let Crypto_status: CCCryptorStatus = CCCrypt(operation, algoritm, options, (keyData as NSData).bytes, keyLength, (ivData as NSData).bytes, (data as NSData).bytes, (data as NSData).length, buffer, buffer_size, &num_bytes_encrypted)
if UInt32(Crypto_status) == UInt32(kCCSuccess){
let myResult: NSData = NSData(bytes: buffer, length: num_bytes_encrypted)
free(buffer)
let keyData: NSData = myResult
let hexString = (keyData as Data).base64EncodedString()
print(hexString)
return myResult as Data
}else{
free(buffer)
return Data()
}
}
func testDeCrypt(data:Data, keyData:Data, ivData:Data, operation:Int) -> Data {
let decryptedData = NSMutableData(length: (data as NSData).length)
var num_bytes_decrypted: size_t = 0
let operation = CCOperation(operation)
let algoritm = CCAlgorithm(kCCAlgorithmAES)
let options = CCOptions(kCCOptionPKCS7Padding)
let keyLength = size_t(kCCKeySizeAES256)
let Crypto_status: CCCryptorStatus = CCCrypt(operation, algoritm, options, (keyData as NSData).bytes, keyLength, (ivData as NSData).bytes, (data as NSData).bytes, (data as NSData).length, decryptedData?.mutableBytes, (decryptedData?.length)!, &num_bytes_decrypted)
if UInt32(Crypto_status) == UInt32(kCCSuccess){
decryptedData?.length = num_bytes_decrypted
return decryptedData! as Data
} else {
return Data()
}
}我们可以用Swift加密和解密数据,但是.Net代码的加密数据在Swift.Please中没有被解密,让我知道code.We尝试解密.net加密数据有什么问题,但我们无法解密.net数据。请帮帮我们。我已经试过了几乎所有可用的解决方案。
发布于 2017-05-01 11:59:55
就我测试您的代码C#和Swift而言,导致问题的主要区别是字符串编码。
但是在这里之前,我需要注意的是,您的代码中充斥着关于使用Data和NSData、传递Data或[UInt8]地址等方面的不良实践,其中有些非常关键。
最重要的是这条线:
let buffer = UnsafeMutablePointer<NSData>.allocate(capacity: buffer_size)您需要分配一个buffer_size-byte内存区域,您不希望buffer_size引用NSData。
其他一些脆弱的线条:
let ptrData = myPassData.bytes.assumingMemoryBound(to: Int8.self)
let ptrSalt = saltData.bytes.assumingMemoryBound(to: UInt8.self)
let keyPtr = UnsafeMutablePointer<UInt8>(mutating: key)这些行很大程度上依赖于Swift当前实现的代码生成和当前设置。
简单地说,令人吃惊的是,您的代码似乎没有崩溃。
因此,我开始重写您的Swift代码如下:
func testCrypt(data: Data, keyData: Data, ivData: Data, operation:Int) -> Data {
assert(keyData.count == Int(kCCKeySizeAES128) || keyData.count == Int(kCCKeySizeAES192) || keyData.count == Int(kCCKeySizeAES256))
let buffer_size = data.count + kCCBlockSizeAES128
var buffer: [UInt8] = Array(repeating: 0, count: buffer_size)
var num_bytes_encrypted : size_t = 0
let operation = CCOperation(operation)
let algoritm = CCAlgorithm(kCCAlgorithmAES)
let options = CCOptions(kCCOptionPKCS7Padding)
let cryptoStatus = keyData.withUnsafeBytes {keyDataBytes in
ivData.withUnsafeBytes {ivDataBytes in
data.withUnsafeBytes {dataBytes in
CCCrypt(operation, algoritm, options, keyDataBytes, keyData.count, ivDataBytes, dataBytes, data.count, &buffer, buffer_size, &num_bytes_encrypted)
}
}
}
if cryptoStatus == CCCryptorStatus(kCCSuccess){
let myResult = Data(bytes: buffer, count: num_bytes_encrypted)
return myResult
} else {
return Data()
}
}
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 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, decryptedData.count, &num_bytes_decrypted)
}
}
}
}
if cryptoStatus == CCCryptorStatus(kCCSuccess) {
decryptedData.count = num_bytes_decrypted
return decryptedData
} else {
return Data()
}
}
extension String {
func AESEncryptedString(withKey keyString: String) -> String? {
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), 1024, &key, 48)
let initialVector = Array(key[32..<48])
key = Array(key[0..<32])
let keyData = Data(bytes: key)
let ivData = Data(bytes: initialVector)
let rawData = self.data(using: .unicode)!
let encryptedData = testCrypt(data: rawData, keyData: keyData, ivData: ivData, operation: kCCEncrypt)
let decryptedData = testDeCrypt(data: encryptedData, keyData: keyData, ivData: ivData, operation: kCCDecrypt)
let decrypted = String(bytes: decryptedData, encoding: .unicode)!
print("Encrypted Data: \(encryptedData.base64EncodedString()) \n with count: \(encryptedData.base64EncodedString().characters.count)")
print("Decrypted: \(decrypted)")
let encryptedString = encryptedData.base64EncodedString()
return encryptedString
}
}(String.Encoding.utf16只是String.Encoding.unicode的别名,所以我用.utf16替换了行为.unicode。)
C#代码将字符串转换为字节数组的部分:
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);在Swift中生成Data的部分:
let rawData = self.data(using: .unicode)!这两行生成不同的字节序列,因为.unicode遵循规范的UTF-16表示,其中在结果顶部包含一个BOM,但是System.Text.Encoding.Unicode不添加BOM。
因此,将这两行(包括.unicode )更改为.utf16LittleEndian
let rawData = self.data(using: .utf16LittleEndian)!
let decrypted = String(bytes: decryptedData, encoding: .utf16LittleEndian)!试着看看你从这些变化中得到了什么。
发布于 2017-05-24 17:55:05
Java Code:
public static String Encrypt(String PlainText) throws Exception {
try {
_aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] keyBytes = "jywseolkdiwpkqse".getBytes();
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
byte[] iv = "jywseolkdiwpkqse".getBytes();
IvParameterSpec ivSpec = new IvParameterSpec(iv);
_aesCipher.init(1, (java.security.Key) keySpec, ivSpec);
byte[] plainText = PlainText.getBytes();
byte[] result = _aesCipher.doFinal(plainText);
return Base64.encode(result);
} catch (Exception ex1) {
System.out.println("Exception setting up cipher: "
+ ex1.getMessage() + "\r\n");
ex1.printStackTrace();
return "";
}
}https://stackoverflow.com/questions/43715416
复制相似问题