AES加密.net迅速发展 [英] AES Encryption .net to swift

查看:74
本文介绍了AES加密.net迅速发展的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

.Net代码:

 公共字符串AESEncrypt(字符串clearText,字符串密钥)
{
字符串EncryptionKey =密钥; // MAKV2SPBNI99212;
byte [] clearBytes = Encoding.Unicode.GetBytes(clearText);
使用(Aes加密器= Aes.Create())
{
int迭代= 1024;
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey,new byte [] {0x49、0x76、0x61、0x6e,0x20、0x4d,0x65、0x64、0x76、0x65、0x64、0x65、0x76};} s
cryptoor.Key = pdb.GetBytes(32);
cryptoor.IV = pdb.GetBytes(16);

使用(MemoryStream ms = new MemoryStream())
{
使用(CryptoStream cs = new CryptoStream(ms,cryptoor.CreateEncryptor(),CryptoStreamMode.Write))
{
cs.Write(clearBytes,0,clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray());
}
}
返回clearText;
}

快速代码:

  // MAKV2SPBNI99212密钥

func AESEncryptedString(withKey key:String)->串? {

let salt:阵列< UInt8> = [0x49、0x76、0x61、0x6e,0x20、0x4d,0x65、0x64、0x76、0x65、0x64、0x65、0x76]
let saltData = NSData(字节:盐,长度:13)
let myPassData:NSData = key.data(使用:String.Encoding.utf8)! as NSData
var key = [UInt8](重复:0,计数:48)
var initialVector = [UInt8](重复:0,计数:16)
let ptrData = myPassData.bytes .assumingMemoryBound(至:Int8.self)
let ptrSalt = saltData.bytes.assumingMemoryBound(至:UInt8.self)
let keyPtr = UnsafeMutablePointer< UInt8>(变异:键)


CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2),ptrData,myPassData.length,ptrSalt,saltData.length,CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA1),1024,keyPtr,48)

initialVector = Array 32 ..< 48])

key = Array(key [0 ..< 32])

let keyD = Data(bytes:key)
let ivD = Data(bytes:initialVector)

let rawData = self.data(使用:String.Encoding.unicode)
let cryptoratedData = testCrypt(data:rawData !, keyData:keyD ,ivData:ivD,operation:kCCEncrypt)



让cryptedData = testDeCrypt (data:encryptedData,keyData:keyD,ivData:ivD,operation:kCCDecrypt)

让解密= String(bytes:decryptedData,encoding:String.Encoding.utf16)!

print(加密数据:\(encryptedData.base64EncodedString())\n,计数:\(encryptedData.base64EncodedString()。characters.count))
print( Decrypted:\(decrypted))

letcryptedString = encryptionData.base64EncodedString()

返回encryptedString
}

函数testCrypt(数据:数据,密钥数据:数据,iv数据:数据,操作:整数)->数据{



let buffer_size:size_t =(数据为NSData).length + kCCBlockSizeAES128

let buffer = UnsafeMutablePointer< NSData> .allocate(容量: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(操作,算法,选项,(keyData为NSData).bytes,keyLength,(ivData作为NSData).bytes,(data as NSData).bytes,(数据作为NSData).length,buffer,buffer_size,& num_bytes_encrypted)

如果UInt32(Crypto_status)== UInt32(kCCSuccess){
让myResult:NSData = NSData(字节:缓冲区,长度:num_bytes_encrypted)
空闲(缓冲区)
让keyData:NSData = myResult
让hexStr ing =(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)- >数据{


让解密数据= NSMutableData(长度:(数据作为NSData).length)
var num_bytes_decrypted:size_t = 0
让操作= CCOperation(操作)
let算法= CCAlgorithm(kCCAlgorithmAES)
let选项= CCOptions(kCCOptionPKCS7Padding)
let keyLength = size_t(kCCKeySizeAES256)

let Crypto_status:CCCryptorStatus = CCCrypt(operation,算法,选项,(keyData作为NSData).bytes,keyLength,(ivData作为NSData).bytes,(数据作为NSData).bytes,(数据作为NSData).length,decryptedData?.mutableBytes,(decryptedData?.length)! ,& num_bytes_decrypted)

如果UInt32(Crypto_status)== UInt32(kCCSuccess){
cryptedData?.length = num_bytes_decrypted
返回解密数据! as Data
}否则{
return Data()
}


}

我们能够在Swift中加密和解密数据,但是.Net代码的加密数据不会在Swift中解密。请告诉我代码是否有问题。尝试解密.net中swift的加密数据可以正常工作,但我们无法解密.net数据。请帮助我们。我已经尝试了几乎所有可用的解决方案。

解决方案

据我测试过您的代码(C#和Swift),主要的区别在于您的问题是字符串编码。






但是在去那儿之前,我需要注意的是,您的代码充满了关于使用 Data NSData ,传递 Data 的地址,或 [UInt8] 等,其中一些是至关重要的。



以下一行是超临界的:

  let buffer = UnsafeMutablePointer< NSData> .allocate(容量:buffer_size)

您需要分配 buffer_size 字节的内存区域,而您不希望 buffer_size NSData 的引用。



其他一些易碎的行:

  let ptrData = myPassData.bytes.assumingMemoryBound(至:Int8.self)
让ptrSalt = saltData.bytes.assumingMemoryBound (至:UInt8.self)
let keyPtr = UnsafeMutablePointer< UInt8>(变异:键)

这些行在很大程度上取决于Swift的当前实现的代码生成以及您的当前设置。



简而言之,您的代码似乎可以正常工作不会崩溃。






因此,我开始重新编写Swift代码,如下所示:

  func testCrypt(data:数据,keyData:数据,ivData:数据,操作:Int)->数据{
assert(keyData.count == Int(kCCKeySizeAES128)|| keyData.count == Int(kCCKeySizeAES192)|| keyData.count == Int(kCCKeySizeAES256))

让buffer_size = data.count + kCCBlockSizeAES128
var缓冲区:[UInt8] =数组(重复:0,计数:buffer_size)
var num_bytes_encrypted:size_t = 0
let操作= CCOperation(操作)
let算法= CCAlgorithm(kCCAlgorithmAES)
let选项= CCOptions(kCCOptionPKCS7Padding)

let cryptoStatus = keyData.withUnsafeBytes {keydataBytes in
ivData.withUnsafeBytes {ivDataBytes in
b data.withUnsafeBytes {
中的dataBytes CCCrypt(操作,算法,选项,keyDataBytes,keyData.count,ivDataBytes,dataBytes,data.count,& buffer,buffer_size,& num_bytes_encrypted)
}
}
}

如果cryptoStatus == CCCryptorStatus(kCCSuccess){
let myResult = Data(bytes:buffer,cou nt:num_bytes_encrypted)
return myResult
} else {
return Data()
}
}


func testDeCrypt( data:数据,keyData:数据,ivData:数据,操作:Int)->数据{
assert(keyData.count == Int(kCCKeySizeAES128)|| keyData.count == Int(kCCKeySizeAES192)|| keyData.count == Int(kCCKeySizeAES256))

var cryptoedData =数据(count:data.count)
var num_bytes_decrypted:size_t = 0
let操作= CCOperation(操作)
let算法= CCAlgorithm(kCCAlgorithmAES)
let选项= CCOptions( kCCOptionPKCS7Padding)

让cryptoStatus = keyData.withUnsafeBytes {
中的keyDataBytes ivData.withUnsafeBytes {
data.withUnsafeBytes {ivDataBytes in
data.withUnsafeBytes {dataBytes in
b $ b CCCrypt(操作,算法,选项,keyDataBytes,keyData.count,ivDataBytes,dataBytes,data.count,decryptedDataBytes,decryptedData.count和& num_bytes_decrypted)
}
}
}
}

如果cryptoStatus == CCCryptorStatus(kCCSuccess){
unlockedData.count = num_bytes_decrypted
返回decryptedData
}否则{
return Data()
}
}

扩展字符串{
func AESEncryptedString(withKey keyString:String)->串? {

让盐:[UInt8] = [0x49、0x76、0x61、0x6e,0x20、0x4d,0x65、0x64、0x76、0x65、0x64、0x65、0x76]
var key = [UInt8](重复:0,计数: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 =数据(字节:键)
let ivData =数据(字节:initialVector)

let rawData = self.data(使用.unicode)!
letcryptedData = testCrypt(数据:rawData,keyData:keyData,ivData:ivData,操作:kCCEncrypt)

letcryptedData = testDeCrypt(data:cryptedData,keyData:keyData,ivData:ivData,操作:kCCDecrypt)

让解密=字符串(字节:decryptedData,编码:.unicode)!

print(加密数据:\(encryptedData.base64EncodedString())\n,计数:\(encryptedData.base64EncodedString()。characters.count))
print( 解密:\(解密))

让cryptosentString = cryptosetData.base64EncodedString()

返回加密字符串
}

}

String.Encoding.utf16 只是 String.Encoding.unicode 的别名,因此我将 .utf16 的行替换为 .unicode 。)



您的C#代码将字符串转换为字节数组的部分:

  byte [] clearBytes = Encoding.Unicode.GetBytes(clearText); 

以及在Swift中生成 Data 的部分:

  let rawData = self.data(使用:.unicode)! 

这两行生成不同的字节序列,如 .unicode 符合规范的UTF-16表示形式,该表示形式在结果顶部包含BOM,但 System.Text.Encoding.Unicode 不会添加BOM。 / p>




因此,将包括 .unicode 的两行更改为 .utf16LittleEndian

  let rawData = self.data(使用:.utf16LittleEndian) ! 

让解密的=字符串(字节:解密的数据,编码:.utf16LittleEndian)!

尝试看看这些更改会带来什么。


.Net Code :

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 Code :

 // "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()
        }


    }

We are able to Encrypt and Decrypt data in Swift but Encrypted data of .Net code is not getting decrypted in Swift.Please let me know if anything wrong with the code.We tried decrypting Encrypted data of swift in .net its working fine but we are not able to decrypt the .net data. please help us with that. I have tried almost every solution available.

解决方案

As far as I tested both your codes, C# and Swift, the main difference causing your issue is string encoding.


But before going there, I need to note that your code is full of bad practices about using Data and NSData, passing the address of Data or [UInt8] etc, etc. Some of them are critical.

The one super-ciritical is this line:

let buffer = UnsafeMutablePointer<NSData>.allocate(capacity: buffer_size)

You need to allocate a buffer_size-byte memory region, you do not want buffer_size references to NSData.

Some other fragile lines:

let ptrData = myPassData.bytes.assumingMemoryBound(to: Int8.self)
let ptrSalt = saltData.bytes.assumingMemoryBound(to: UInt8.self)
let keyPtr = UnsafeMutablePointer<UInt8>(mutating: key)

These lines are strongly dependent on the code generation of the current implementation of Swift and on your current settings.

Simply saying, it is astonishing that your code seems to work without crashing.


So, I started with re-writing your Swift code as follows:

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 is just an alias of String.Encoding.unicode, so I replaced the line using .utf16 to .unicode.)

The part your C# code converts string to byte array:

byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);

And the part generating Data in Swift:

let rawData = self.data(using: .unicode)!

Those two lines generate different byte sequences, as .unicode conforms to canonical UTF-16 representation, which contains a BOM at the top of the result, but System.Text.Encoding.Unicode does not add a BOM.


So, change the two lines including .unicode to .utf16LittleEndian:

let rawData = self.data(using: .utf16LittleEndian)!

let decrypted = String(bytes: decryptedData, encoding: .utf16LittleEndian)!

Try and see what you get with these changes.

这篇关于AES加密.net迅速发展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆