【问题标题】:AES Encrypt and DecryptAES 加密和解密
【发布时间】:2015-01-20 05:28:35
【问题描述】:

我通过 swift 编写了一个应用程序,我需要 AES 加密和解密功能,我从另一个 .Net 解决方案接收到加密数据,但我找不到可以做的事情。

这是我的 .net 加密:

 public static byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
    {
        byte[] encryptedBytes = null;

        byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

        using (MemoryStream ms = new MemoryStream())
        {
            using (RijndaelManaged AES = new RijndaelManaged())
            {
                AES.KeySize = 256;
                AES.BlockSize = 128;

                var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
                AES.Key = key.GetBytes(AES.KeySize / 8);
                AES.IV = key.GetBytes(AES.BlockSize / 8);

                AES.Mode = CipherMode.CBC;

                using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
                    cs.Close();
                }
                encryptedBytes = ms.ToArray();
            }
        }

        return encryptedBytes;
    }

我需要快速解密函数。

【问题讨论】:

  • 我找到了,github.com/Pakhee/Cross-platform-AES-encryption 我可以将Objective-C文件添加到我的项目中,但是调用方法和返回值有很多问题,swift和objective-C不兼容: (
  • 你找到解决方案了吗,我需要同样的 iOS 解决方案。

标签: ios swift encryption aes cryptoswift


【解决方案1】:

CryptoSwift Example

更新到 Swift 2

import Foundation
import CryptoSwift

extension String {
    func aesEncrypt(key: String, iv: String) throws -> String{
        let data = self.dataUsingEncoding(NSUTF8StringEncoding)
        let enc = try AES(key: key, iv: iv, blockMode:.CBC).encrypt(data!.arrayOfBytes(), padding: PKCS7())
        let encData = NSData(bytes: enc, length: Int(enc.count))
        let base64String: String = encData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0));
        let result = String(base64String)
        return result
    }

    func aesDecrypt(key: String, iv: String) throws -> String {
        let data = NSData(base64EncodedString: self, options: NSDataBase64DecodingOptions(rawValue: 0))
        let dec = try AES(key: key, iv: iv, blockMode:.CBC).decrypt(data!.arrayOfBytes(), padding: PKCS7())
        let decData = NSData(bytes: dec, length: Int(dec.count))
        let result = NSString(data: decData, encoding: NSUTF8StringEncoding)
        return String(result!)
    }
}

用法:

let key = "bbC2H19lkVbQDfakxcrtNMQdd0FloLyw" // length == 32
let iv = "gqLOHUioQ0QjhuvI" // length == 16
let s = "string to encrypt"
let enc = try! s.aesEncrypt(key, iv: iv)
let dec = try! enc.aesDecrypt(key, iv: iv)
print(s) // string to encrypt
print("enc:\(enc)") // 2r0+KirTTegQfF4wI8rws0LuV8h82rHyyYz7xBpXIpM=
print("dec:\(dec)") // string to encrypt
print("\(s == dec)") // true

确保 iv (16) 和 key (32) 的长度正确,然后您就不会点击“块大小和初始化向量必须是相同长度!”错误。

【讨论】:

  • 此代码在进行加密时会抛出错误Block size and Initialization Vector must be the same length!。
  • @Deekor 我刚刚添加了使用示例。 iv 和 key 的长度必须正确。 iv 为 16,key 为 32。
  • 有没有办法从键值创建IV?
  • 加密该字符串时出现 nil 错误 "q3xnpwB3d3+UCW1zt6LM4ePQAVkOw/ZRF5qBB7J2YTdqlZaWSzZR+oXEAOlgkt43AoY2BhqjBltf1e7ZRNs5XIPHTOkNqgYfAPzfsGUPo+8="出了什么问题?
  • 请注意,CryptoSwift 比 Common Crypto 慢 500 到 1000 倍。
【解决方案2】:

CryptoSwift Example

更新SWIFT 4.*

func aesEncrypt() throws -> String {
    let encrypted = try AES(key: KEY, iv: IV, padding: .pkcs7).encrypt([UInt8](self.data(using: .utf8)!))
    return Data(encrypted).base64EncodedString()
}

func aesDecrypt() throws -> String {
    guard let data = Data(base64Encoded: self) else { return "" }
    let decrypted = try AES(key: KEY, iv: IV, padding: .pkcs7).decrypt([UInt8](data))
    return String(bytes: decrypted, encoding: .utf8) ?? self
}

【讨论】:

  • 最好避免使用 CryptoSwift,除此之外,它比基于 Common Crypto 的实现慢 500 到 1000 倍。 Apple 的 Common Crypto 已通过 FIPS 认证,因此经过严格审查,使用 CryptoSwift 在正确性和安全性方面是有机会的。
  • 我正在使用它来加密聊天消息。基本上你说的是这不是个好主意吗?我已经用了一段时间了,没有发现有什么不好的……
  • 基本上每一次数据泄露都可以说“我已经使用了一段时间,没有发现任何不好的事情”……但随后发生了一些不好的事情。就像安全带一样,何必呢。
  • @zaph 如果您能提供您推荐的实现示例,那就太好了。
  • @zaph 你在说什么数据泄露?你怎么能解密加密的字符串,不知道它是用什么方法解密的,KEY和IV??
【解决方案3】:

SHS 提供的代码对我不起作用,但这个显然对我有用(我使用了桥接头:#import <CommonCrypto/CommonCrypto.h>):

extension String {

    func aesEncrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
        if let keyData = key.data(using: String.Encoding.utf8),
            let data = self.data(using: String.Encoding.utf8),
            let cryptData    = NSMutableData(length: Int((data.count)) + kCCBlockSizeAES128) {


            let keyLength              = size_t(kCCKeySizeAES128)
            let operation: CCOperation = UInt32(kCCEncrypt)
            let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
            let options:   CCOptions   = UInt32(options)



            var numBytesEncrypted :size_t = 0

            let cryptStatus = CCCrypt(operation,
                                      algoritm,
                                      options,
                                      (keyData as NSData).bytes, keyLength,
                                      iv,
                                      (data as NSData).bytes, data.count,
                                      cryptData.mutableBytes, cryptData.length,
                                      &numBytesEncrypted)

            if UInt32(cryptStatus) == UInt32(kCCSuccess) {
                cryptData.length = Int(numBytesEncrypted)
                let base64cryptString = cryptData.base64EncodedString(options: .lineLength64Characters)
                return base64cryptString


            }
            else {
                return nil
            }
        }
        return nil
    }

    func aesDecrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
        if let keyData = key.data(using: String.Encoding.utf8),
            let data = NSData(base64Encoded: self, options: .ignoreUnknownCharacters),
            let cryptData    = NSMutableData(length: Int((data.length)) + kCCBlockSizeAES128) {

            let keyLength              = size_t(kCCKeySizeAES128)
            let operation: CCOperation = UInt32(kCCDecrypt)
            let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
            let options:   CCOptions   = UInt32(options)

            var numBytesEncrypted :size_t = 0

            let cryptStatus = CCCrypt(operation,
                                      algoritm,
                                      options,
                                      (keyData as NSData).bytes, keyLength,
                                      iv,
                                      data.bytes, data.length,
                                      cryptData.mutableBytes, cryptData.length,
                                      &numBytesEncrypted)

            if UInt32(cryptStatus) == UInt32(kCCSuccess) {
                cryptData.length = Int(numBytesEncrypted)
                let unencryptedMessage = String(data: cryptData as Data, encoding:String.Encoding.utf8)
                return unencryptedMessage
            }
            else {
                return nil
            }
        }
        return nil
    }


}

来自我的ViewController:

 let encoded = message.aesEncrypt(key: keyString, iv: iv)
 let unencode = encoded?.aesDecrypt(key: keyString, iv: iv)

【讨论】:

  • 工作就像一个魅力。然后在我的 php 代码中使用以下内容。 $decryptedData = openssl_decrypt(base64_decode($data), OPENSSL_CIPHER_NAME, $key, OPENSSL_RAW_DATA, $iv);
  • #user1094081 你在Objective c中有相同的吗?
  • 工作就像一个魅力。服务器端C#代码和服务端Crypto JS,非常容易实现,因为有String输入和String输出
【解决方案4】:

有一个有趣的“pure-swift”开源库:

AES 解密示例(来自项目 README.md 文件):

import CryptoSwift
let setup = (key: keyData, iv: ivData)
let decryptedAES = AES(setup).decrypt(encryptedData)

【讨论】:

  • 收到此错误“密码”类型没有成员“AES”
  • @QadirHussain 试试AES 而不是Cipher.AES。
  • 从哪里获得 ivData 的价值?
【解决方案5】:

我使用 CommonCrypto 通过来自Easy to use Swift implementation of CommonCrypto HMAC 的 MihaelIsaev/HMAC.swift 的代码生成哈希。此实现不使用 Bridging-Header,而是创建 Module 文件。

现在要使用AESEncrypt和Decrypt,我直接在HAMC.swift的“extension String {”里面添加了函数。

func aesEncrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
    if let keyData = key.dataUsingEncoding(NSUTF8StringEncoding),
        data = self.dataUsingEncoding(NSUTF8StringEncoding),
        cryptData    = NSMutableData(length: Int((data.length)) + kCCBlockSizeAES128) {

            let keyLength              = size_t(kCCKeySizeAES128)
            let operation: CCOperation = UInt32(kCCEncrypt)
            let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
            let options:   CCOptions   = UInt32(options)

            var numBytesEncrypted :size_t = 0

            let cryptStatus = CCCrypt(operation,
                algoritm,
                options,
                keyData.bytes, keyLength,
                iv,
                data.bytes, data.length,
                cryptData.mutableBytes, cryptData.length,
                &numBytesEncrypted)

            if UInt32(cryptStatus) == UInt32(kCCSuccess) {
                cryptData.length = Int(numBytesEncrypted)
                let base64cryptString = cryptData.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
                return base64cryptString
            }
            else {
                return nil
            }
    }
    return nil
}

func aesDecrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
    if let keyData = key.dataUsingEncoding(NSUTF8StringEncoding),
        data = NSData(base64EncodedString: self, options: .IgnoreUnknownCharacters),
        cryptData    = NSMutableData(length: Int((data.length)) + kCCBlockSizeAES128) {

            let keyLength              = size_t(kCCKeySizeAES128)
            let operation: CCOperation = UInt32(kCCDecrypt)
            let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
            let options:   CCOptions   = UInt32(options)

            var numBytesEncrypted :size_t = 0

            let cryptStatus = CCCrypt(operation,
                algoritm,
                options,
                keyData.bytes, keyLength,
                iv,
                data.bytes, data.length,
                cryptData.mutableBytes, cryptData.length,
                &numBytesEncrypted)

            if UInt32(cryptStatus) == UInt32(kCCSuccess) {
                cryptData.length = Int(numBytesEncrypted)
                let unencryptedMessage = String(data: cryptData, encoding:NSUTF8StringEncoding)
                return unencryptedMessage
            }
            else {
                return nil
            }
    }
    return nil
}

函数取自RNCryptor。这是散列函数和单个文件“HMAC.swift”中的一个简单添加,无需使用 Bridging-header。我希望这对需要散列和 AES 加密/解密的 swift 开发人员有用。

使用 AESDecrypt 的示例如下。

 let iv = "AA-salt-BBCCDD--" // should be of 16 characters.
 //here we are convert nsdata to String
 let encryptedString = String(data: dataFromURL, encoding: NSUTF8StringEncoding)
 //now we are decrypting
 if let decryptedString = encryptedString?.aesDecrypt("12345678901234567890123456789012", iv: iv) // 32 char pass key
 {                    
      // Your decryptedString
 }

【讨论】:

【解决方案6】:

您可以使用 iOS 中的 CommonCrypto 或 CryptoSwift 作为外部库。下面有两种工具的实现。也就是说,应该测试带有 AES 的 CommonCrypto 输出,因为在 CC 文档中并不清楚它使用哪种 AES 模式。

Swift 4.2 中的 CommonCrypto

导入 CommonCrypto func 加密(数据:数据)-> 数据 { 返回 cryptCC(数据:数据,密钥:密钥,操作:kCCEncrypt) } func 解密(数据:数据)-> 数据 { 返回 cryptCC(数据:数据,密钥:密钥,操作:kCCDecrypt) } private func cryptCC(data: Data, key: String operation: Int) -> Data { guard key.count == kCCKeySizeAES128 else { 致命错误(“密钥大小失败!”) } var ivBytes: [UInt8] var inBytes: [UInt8] var outLength: Int 如果操作 == kCCEncrypt { ivBytes = [UInt8](重复:0,计数:kCCBlockSizeAES128) 守卫 kCCSuccess == SecRandomCopyBytes(kSecRandomDefault, ivBytes.count, &ivBytes) else { fatalError("IV 创建失败!") } inBytes = 数组(数据) outLength = data.count + kCCBlockSizeAES128 } 别的 { ivBytes = Array(Array(data).dropLast(data.count - kCCBlockSizeAES128)) inBytes = Array(Array(data).dropFirst(kCCBlockSizeAES128)) outLength = inBytes.count } var outBytes = [UInt8](重复:0,计数:outLength) var bytesMutated = 0 保护 kCCSuccess == CCCrypt(CCOperation(operation), CCAlgorithm(kCCAlgorithmAES128), CCOptions(kCCOptionPKCS7Padding), Array(key), kCCKeySizeAES128, &ivBytes, &inBytes, inBytes.count, &outBytes, outLength, &bytesMutated) else { 致命错误(“密码学操作\(操作)失败”) } var outData = Data(bytes: &outBytes, count: bytesMutated) 如果操作 == kCCEncrypt { ivBytes.append(contentsOf:数组(outData)) outData = 数据(字节:ivBytes) } 返回数据 }

Swift 4.2 中的 CryptoSwift v0.14

枚举操作{ 大小写加密 案例解密 } 私人让 keySizeAES128 = 16 私有让 aesBlockSize = 16 func 加密(数据:数据,密钥:字符串)-> 数据 { 返回加密(数据:数据,密钥:密钥,操作:.encrypt) } func 解密(数据:数据,密钥:字符串)-> 数据 { 返回加密(数据:数据,密钥:密钥,操作:.decrypt) } private func crypt(数据:数据,密钥:字符串,操作:操作)->数据{ 保护 key.count == keySizeAES128 else { 致命错误(“密钥大小失败!”) } var outData:数据? = 无 如果操作 == .encrypt { var ivBytes = [UInt8](重复:0,计数:aesBlockSize) 守卫 0 == SecRandomCopyBytes(kSecRandomDefault, ivBytes.count, &ivBytes) else { fatalError("IV 创建失败!") } 做 { let aes = try AES(key: Array(key.data(using: .utf8)!), blockMode: CBC(iv: ivBytes)) 让加密 = 尝试 aes.encrypt(Array(data)) ivBytes.append(contentsOf:加密) outData = 数据(字节:ivBytes) } 抓住 { print("加密错误:\(error)") } } 别的 { 让 ivBytes = Array(Array(data).dropLast(data.count - aesBlockSize)) 让 inBytes = Array(Array(data).dropFirst(aesBlockSize)) 做 { let aes = try AES(key: Array(key.data(using: .utf8)!), blockMode: CBC(iv: ivBytes)) 让解密 = 尝试 aes.decrypt(inBytes) outData = Data(字节:解密) } 抓住 { print("解密错误:\(error)") } } 返回数据! }

【讨论】:

  • 刚刚在这个答案的CommonCrypto 版本中发现了一个非常大的错误。至少,这是 Swift 5.2 的一个问题——也许它不是 Swift 4.2 的问题。问题是只有密钥的第一个字符似乎很重要。我可以使用以相同字母开头的任何相同长度的密钥来解密我的消息!问题似乎出在Array(key) 作为CCCrypt 中的第四个参数传递。如果我只用key 替换它,它似乎可以正常工作。
【解决方案7】:

CryptoSwift 是一个非常有趣的项目,但目前它有一些 AES 速度限制。如果您需要进行一些严肃的加密,请小心 - 经历实现 CommonCrypto 的桥梁的痛苦可能是值得的。

BigUps 到 Marcin 实现 pureSwift

【讨论】:

  • 是的,使用 CryptoSwift 的 AES 加密比 Common Crypto 慢 500 到 1000 倍,这是因为 Common Crypto 使用了硬件加密功能而 CryptoSwift 没有。
【解决方案8】:

更新 Swift 4.2

例如,我们将一个字符串加密为 base64 编码的字符串。然后我们将其解密为可读字符串。 (这与我们的输入字符串相同)。

就我而言,我使用它来加密字符串并将其嵌入到二维码中。然后另一方对其进行扫描并解密。所以中级不会理解二维码。

第 1 步:加密字符串“Encrypt My Message 123”

第 2 步: 加密 base64Encoded 字符串:+yvNjiD7F9/JKmqHTc/Mjg==(同样印在二维码上)

第三步:扫描解密字符串“+yvNjiD7F9/JKmqHTc/Mjg=="

第 4 步:得到最终结果 - “加密我的消息 123”

加密和解密函数

func encryption(stringToEncrypt: String) -> String{
    let key = "MySecretPKey"
    //let iv = "92c9d2c07a9f2e0a"
    let data = stringToEncrypt.data(using: .utf8)
    let keyD = key.data(using: .utf8)
    let encr = (data as NSData?)!.aes128EncryptedData(withKey: keyD)
    let base64String: String = (encr as NSData?)!.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
    print(base64String)
    return base64String
}

func decryption(encryptedString:String) -> String{
    let key = "MySecretPKey"
    //let iv = "92c9d2c07a9f2e0a"
    let keyD = key.data(using: .utf8)
    let decrpStr = NSData(base64Encoded: encryptedString, options: NSData.Base64DecodingOptions(rawValue: 0))
    let dec = (decrpStr)!.aes128DecryptedData(withKey: keyD)
    let backToString = String(data: dec!, encoding: String.Encoding.utf8)
    print(backToString!)
    return backToString!
}

用法:

    let enc = encryption(stringToEncrypt: "Encrypt My Message 123")
    let decryptedString = decryption(encryptedString: enc)
    print(decryptedString) 

支持 AES 加密功能的类,这些是用 Objective-C 编写的。所以对于swift,你需要使用桥头来支持这些。

类名:NSData+AES.h

#import <Foundation/Foundation.h>

@interface NSData (AES)

- (NSData *)AES128EncryptedDataWithKey:(NSData *)key;
- (NSData *)AES128DecryptedDataWithKey:(NSData *)key;
- (NSData *)AES128EncryptedDataWithKey:(NSData *)key iv:(NSData *)iv;
- (NSData *)AES128DecryptedDataWithKey:(NSData *)key iv:(NSData *)iv;

@end

类名:NSData+AES.m

#import "NSData+AES.h"
#import <CommonCrypto/CommonCryptor.h>

@implementation NSData (AES)

- (NSData *)AES128EncryptedDataWithKey:(NSData *)key
{
    return [self AES128EncryptedDataWithKey:key iv:nil];
}

- (NSData *)AES128DecryptedDataWithKey:(NSData *)key
{
    return [self AES128DecryptedDataWithKey:key iv:nil];
}

- (NSData *)AES128EncryptedDataWithKey:(NSData *)key iv:(NSData *)iv
{
    return [self AES128Operation:kCCEncrypt key:key iv:iv];
}

- (NSData *)AES128DecryptedDataWithKey:(NSData *)key iv:(NSData *)iv
{
    return [self AES128Operation:kCCDecrypt key:key iv:iv];
}

- (NSData *)AES128Operation:(CCOperation)operation key:(NSData *)key iv:(NSData *)iv
{

    NSUInteger dataLength = [self length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);

    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(operation,
                                          kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding | kCCOptionECBMode,
                                          key.bytes,
                                          kCCBlockSizeAES128,
                                          iv.bytes,
                                          [self bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }
    free(buffer);
    return nil;
}

@end

希望对你有帮助。

谢谢!!!

【讨论】:

  • 正是我想要的。谢谢
  • 在解密字符串中获取零值你能帮我吗..我关注你的代码。我只有密钥和加密字符串
【解决方案9】:

Swift4:

let key = "ccC2H19lDDbQDfakxcrtNMQdd0FloLGG" // length == 32
let iv = "ggGGHUiDD0Qjhuvv" // length == 16
func encryptFile(_ path: URL) -> Bool{
    do{
        let data = try Data.init(contentsOf: path)
        let encodedData = try data.aesEncrypt(key: key, iv: iv)
        try encodedData.write(to: path)
        return true
    }catch{
        return false
    }
}

func decryptFile(_ path: URL) -> Bool{
    do{
        let data = try Data.init(contentsOf: path)
        let decodedData = try data.aesDecrypt(key: key, iv: iv)
        try decodedData.write(to: path)
        return true
    }catch{
        return false
    }
}

安装 CryptoSwift

import CryptoSwift
extension Data {
    func aesEncrypt(key: String, iv: String) throws -> Data{
        let encypted = try AES(key: key.bytes, blockMode: CBC(iv: iv.bytes), padding: .pkcs7).encrypt(self.bytes)
        return Data(bytes: encypted)
    }

    func aesDecrypt(key: String, iv: String) throws -> Data {
        let decrypted = try AES(key: key.bytes, blockMode: CBC(iv: iv.bytes), padding: .pkcs7).decrypt(self.bytes)
        return Data(bytes: decrypted)
    }
}

【讨论】:

    【解决方案10】:

    我找到了解决方案,这是一个很好的库。

    跨平台256bit AES加密/解密。

    该项目包含 256 位 AES 加密的实现,适用于所有平台(C#、iOS、Android)。关键目标之一是通过简单的实现使 AES 在所有平台上工作。

    支持的平台: IOS , 安卓 , Windows (C#)。

    https://github.com/Pakhee/Cross-platform-AES-encryption

    【讨论】:

    • 这是一个非常糟糕的库。 a) 如果 Key 和 IV 的大小不合适,出于某种原因,它们会用 null 填充。这很糟糕,因为人们只是将它与密码一起使用,但密码没有足够的熵来用作密钥!相反,密钥可以从密码中派生,例如 PBKDF2 或 Argon2。 b)这个库根本不提供身份验证。 c) IV 出于某种原因是基于文本的而不是二进制的。 d) 用户需要自己管理 IV,而且很可能会出错。
    • 使用这个库时加密和解密都有问题。
    【解决方案11】:

    这是一篇相当老的帖子,但 XCode 10 添加了 CommonCrypto 模块,因此您不需要模块映射。还有 Swift 5,不需要烦人的演员表。

    你可以这样做:

    func decrypt(_ data: Data, iv: Data, key: Data) throws -> String {
    
        var buffer = [UInt8](repeating: 0, count: data.count + kCCBlockSizeAES128)
        var bufferLen: Int = 0
    
        let status = CCCrypt(
            CCOperation(kCCDecrypt),
            CCAlgorithm(kCCAlgorithmAES128),
            CCOptions(kCCOptionPKCS7Padding),
            [UInt8](key),
            kCCBlockSizeAES128,
            [UInt8](iv),
            [UInt8](data),
            data.count,
            &buffer,
            buffer.count,
            &bufferLen
        )
    
        guard status == kCCSuccess,
            let str = String(data: Data(bytes: buffer, count: bufferLen),
                             encoding: .utf8) else {
                                throw NSError(domain: "AES", code: -1, userInfo: nil)
        }
    
        return str
    }
    

    【讨论】:

      【解决方案12】:

      您可以复制和粘贴这些方法(Swift 4+):

          class func encryptMessage(message: String, encryptionKey: String, iv: String) -> String? {
              if let aes = try? AES(key: encryptionKey, iv: iv),
                  let encrypted = try? aes.encrypt(Array<UInt8>(message.utf8)) {
                  return encrypted.toHexString()
              }
              return nil
          }
      
          class func decryptMessage(encryptedMessage: String, encryptionKey: String, iv: String) -> String? {
              if let aes = try? AES(key: encryptionKey, iv: iv),
                  let decrypted = try? aes.decrypt(Array<UInt8>(hex: encryptedMessage)) {
                  return String(data: Data(bytes: decrypted), encoding: .utf8)
              }
              return nil
          }
      

      示例:

      let encryptMessage = encryptMessage(message: "Hello World!", encryptionKey: "mykeymykeymykey1", iv: "myivmyivmyivmyiv")    
      // Output of encryptMessage is: 649849a5e700d540f72c4429498bf9f4
      
      let decryptedMessage = decryptMessage(encryptedMessage: encryptMessage, encryptionKey: "mykeymykeymykey1", iv: "myivmyivmyivmyiv")
      // Output of decryptedMessage is: Hello World!
      

      别忘了encryptionKey & iv 应该是16 字节。


      【讨论】:

      • 使用未解析的标识符“AES”;你的意思是“是”吗?
      • 不,您不能只是复制和粘贴这些方法。 AES 没有在任何地方声明。你做了什么?将CryptoSwift 添加到您的项目中而不告诉我们?
      【解决方案13】:

      试试下面的代码,它对我有用。

      AES 加密

      public static String getEncryptedString(String value) {
              try {
                byte[] key = your Key in byte array;
                byte[] input = sault in byte array
      
                  return Base64.encodeToString(encrypt(value.getBytes("UTF-8"), key, input), Base64.DEFAULT);
              } catch (UnsupportedEncodingException e) {
                  return "";
              }
          }
      
      
       public static byte[] encrypt(byte[] data, byte[] key, byte[] ivs) {
              try {
                  Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                  SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
                  byte[] finalIvs = new byte[16];
                  int len = ivs.length > 16 ? 16 : ivs.length;
                  System.arraycopy(ivs, 0, finalIvs, 0, len);
                  IvParameterSpec ivps = new IvParameterSpec(finalIvs);
                  cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivps);
                  return cipher.doFinal(data);
              } catch (Exception e) {
                  e.printStackTrace();
              }
              return null;
          }
      

      AES 解密

       public static String decrypt(String encrypted) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
      
                  byte[] key = your Key in byte array;
                  byte[] input = sault in byte array
      
      
                  SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
                  IvParameterSpec ivSpec = new IvParameterSpec(input);
                  Cipher ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                  ecipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
                  byte[] raw = Base64.decode(encrypted, Base64.DEFAULT);
                  byte[] originalBytes = ecipher.doFinal(raw);
                  String original = new String(originalBytes, "UTF8");
                  return original;
              }
      

      【讨论】:

        猜你喜欢
        • 2014-01-05
        • 2019-01-06
        • 1970-01-01
        • 1970-01-01
        • 2012-02-24
        • 2015-09-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多