首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AES加密.net到.net

AES加密.net到.net
EN

Stack Overflow用户
提问于 2017-05-01 06:53:29
回答 2查看 1.5K关注 0票数 3

.Net代码:

代码语言:javascript
复制
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代码:

代码语言:javascript
复制
 // "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数据。请帮帮我们。我已经试过了几乎所有可用的解决方案。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-05-01 11:59:55

就我测试您的代码C#和Swift而言,导致问题的主要区别是字符串编码。

但是在这里之前,我需要注意的是,您的代码中充斥着关于使用DataNSData、传递Data[UInt8]地址等方面的不良实践,其中有些非常关键。

最重要的是这条线:

代码语言:javascript
复制
let buffer = UnsafeMutablePointer<NSData>.allocate(capacity: buffer_size)

您需要分配一个buffer_size-byte内存区域,您不希望buffer_size引用NSData

其他一些脆弱的线条:

代码语言:javascript
复制
let ptrData = myPassData.bytes.assumingMemoryBound(to: Int8.self)
let ptrSalt = saltData.bytes.assumingMemoryBound(to: UInt8.self)
let keyPtr = UnsafeMutablePointer<UInt8>(mutating: key)

这些行很大程度上依赖于Swift当前实现的代码生成和当前设置。

简单地说,令人吃惊的是,您的代码似乎没有崩溃。

因此,我开始重写您的Swift代码如下:

代码语言:javascript
复制
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#代码将字符串转换为字节数组的部分:

代码语言:javascript
复制
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);

在Swift中生成Data的部分:

代码语言:javascript
复制
let rawData = self.data(using: .unicode)!

这两行生成不同的字节序列,因为.unicode遵循规范的UTF-16表示,其中在结果顶部包含一个BOM,但是System.Text.Encoding.Unicode不添加BOM。

因此,将这两行(包括.unicode )更改为.utf16LittleEndian

代码语言:javascript
复制
let rawData = self.data(using: .utf16LittleEndian)!

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

试着看看你从这些变化中得到了什么。

票数 3
EN

Stack Overflow用户

发布于 2017-05-24 17:55:05

代码语言:javascript
复制
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 "";
        }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43715416

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档