栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

迅速进行AES加密

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

迅速进行AES加密

确保使用相同的参数,这些参数似乎是带有iv

PKCS5Padding
(实际上是PKCS#7)填充和16字节(128位)密钥的CBC模式的AES 。

PKCS#5填充和PKCS#7填充基本相同,有时出于历史原因,有时将PKCS#5填充指定为与AES一起使用,但实际填充为PKCS#7。

确保密钥,iv和加密数据的编码都匹配。十六进制将它们转储到两个平台上以确保它们相同。加密功能并不难使用,如果所有输入参数正确,则输出将正确。

为了使其更加安全,iv应该是随机字节,并放在加密数据之前,以便在解密期间使用。

跨平台的AES 加密使用256位密钥,以便将无法工作原样。

例:

迅捷2

// operation: kCCEncrypt or kCCDecryptfunc testCrypt(data data:[UInt8], keydata:[UInt8], ivdata:[UInt8], operation:Int) -> [UInt8]? {    let cryptLength  = size_t(data.count+kCCBlockSizeAES128)    var cryptData    = [UInt8](count:cryptLength, repeatedValue:0)    let keyLength  = size_t(kCCKeySizeAES128)    let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)    let options:  CCOptions   = UInt32(kCCOptionPKCS7Padding)    var numBytesEncrypted :size_t = 0    let cryptStatus = CCCrypt(CCOperation(operation),        algoritm,        options,        keyData, keyLength,        ivData,        data, data.count,        &cryptData, cryptLength,        &numBytesEncrypted)    if UInt32(cryptStatus) == UInt32(kCCSuccess) {        cryptData.removeRange(numBytesEncrypted..<cryptData.count)    } else {        print("Error: (cryptStatus)")    }    return cryptData;}let message       = "Don´t try to read this text. Top Secret Stuff"let messageData   = Array(message.utf8)let keyData       = Array("12345678901234567890123456789012".utf8)let ivData        = Array("abcdefghijklmnop".utf8)let encryptedData = testCrypt(data:messageData,   keydata:keyData, ivdata:ivData, operation:kCCEncrypt)!let decryptedData = testCrypt(data:encryptedData, keydata:keyData, ivdata:ivData, operation:kCCDecrypt)!var decrypted     = String(bytes:decryptedData, encoding:NSUTF8StringEncoding)!print("message:       (message)");print("messagedata:   (NSData(bytes:messageData,   length:messageData.count))");print("keydata:       (NSData(bytes:keyData,       length:keyData.count))");print("ivdata:        (NSData(bytes:ivData,        length:ivData.count))");print("encrypteddata: (NSData(bytes:encryptedData, length:encryptedData.count))");print("decrypteddata: (NSData(bytes:decryptedData, length:decryptedData.count))");print("decrypted:     (String(bytes:decryptedData,encoding:NSUTF8StringEncoding)!)");

输出:

消息:不要尝试阅读此文本。最高机密的东西  messageData:446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666  keyData:31323334 35363738 39303132 33343536 37383930 31323334 35363738 39303132  ivData:61626364 65666768 696a6b6c 6d6e6f70  加密数据:b1b6dc17 62eaf3f8 baa1cb87 21ddc35c dee803ed fb320020 85794848 21206943 a85feb5b c8ee58fc d6fb664b 96b81114  解密数据:446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666  解密:请勿尝试阅读此文本。最高机密的东西

Swift 3与

[UInt8]
类型

func testCrypt(data:[UInt8], keydata:[UInt8], ivdata:[UInt8], operation:Int) -> [UInt8]? {    let cryptLength  = size_t(data.count+kCCBlockSizeAES128)    var cryptData    = [UInt8](repeating:0, count:cryptLength)    let keyLength  = size_t(kCCKeySizeAES128)    let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)    let options:  CCOptions   = UInt32(kCCOptionPKCS7Padding)    var numBytesEncrypted :size_t = 0    let cryptStatus = CCCrypt(CCOperation(operation),        algoritm,        options,        keyData, keyLength,        ivData,        data, data.count,        &cryptData, cryptLength,        &numBytesEncrypted)    if UInt32(cryptStatus) == UInt32(kCCSuccess) {        cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)    } else {        print("Error: (cryptStatus)")    }    return cryptData;}

带有

Data
类型的Swift 3和4

func testCrypt(data:Data, keydata:Data, ivdata:Data, operation:Int) -> Data {    let cryptLength  = size_t(data.count + kCCBlockSizeAES128)    var cryptData = Data(count:cryptLength)    let keyLength  = size_t(kCCKeySizeAES128)    let options   = CCOptions(kCCOptionPKCS7Padding)    var numBytesEncrypted :size_t = 0    let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in        data.withUnsafeBytes {dataBytes in ivData.withUnsafeBytes {ivBytes in     keyData.withUnsafeBytes {keyBytes in         CCCrypt(CCOperation(operation),        CCAlgorithm(kCCAlgorithmAES),        options,        keyBytes, keyLength,        ivBytes,        dataBytes, data.count,        cryptBytes, cryptLength,        &numBytesEncrypted)     } }        }    }    if UInt32(cryptStatus) == UInt32(kCCSuccess) {        cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)    } else {        print("Error: (cryptStatus)")    }    return cryptData;}let message     = "Don´t try to read this text. Top Secret Stuff"let messageData = message.data(using:String.Encoding.utf8)!let keyData     = "12345678901234567890123456789012".data(using:String.Encoding.utf8)!let ivData      = "abcdefghijklmnop".data(using:String.Encoding.utf8)!let encryptedData = testCrypt(data:messageData,   keydata:keyData, ivdata:ivData, operation:kCCEncrypt)let decryptedData = testCrypt(data:encryptedData, keydata:keyData, ivdata:ivData, operation:kCCDecrypt)var decrypted     = String(bytes:decryptedData, encoding:String.Encoding.utf8)!

失效文档部分的示例:

CBC模式下的AES加密,随机IV(Swift 3+)

iv前缀为加密数据

aesCBC128Encrypt
将创建一个随机IV并以加密代码为前缀。
aesCBC128Decrypt
在解密期间将使用带前缀的IV。

输入是数据,键是数据对象。如果需要,则使用诸如base64之类的编码形式在调用方法中来回转换。

密钥的长度应精确为128位(16字节),192位(24字节)或256位(32字节)。如果使用其他密钥大小,将引发错误。

默认设置为PKCS#7填充。

此示例需要通用加密
。必须在项目中具有桥接头:

#import <CommonCrypto/CommonCrypto.h>

将添加
Security.framework
到项目中。

这是示例,而不是生产代码。

enum AESError: Error {    case KeyError((String, Int))    case IVError((String, Int))    case CryptorError((String, Int))}// The iv is prefixed to the encrypted datafunc aesCBCEncrypt(data:Data, keydata:Data) throws -> Data {    let keyLength = keyData.count    let validKeyLengths = [kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256]    if (validKeyLengths.contains(keyLength) == false) {        throw AESError.KeyError(("Invalid key length", keyLength))    }    let ivSize = kCCBlockSizeAES128;    let cryptLength = size_t(ivSize + data.count + kCCBlockSizeAES128)    var cryptData = Data(count:cryptLength)    let status = cryptData.withUnsafeMutableBytes {ivBytes in        SecRandomCopyBytes(kSecRandomDefault, kCCBlockSizeAES128, ivBytes)    }    if (status != 0) {        throw AESError.IVError(("IV generation failed", Int(status)))    }    var numBytesEncrypted :size_t = 0    let options   = CCOptions(kCCOptionPKCS7Padding)    let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in        data.withUnsafeBytes {dataBytes in keyData.withUnsafeBytes {keyBytes in     CCCrypt(CCOperation(kCCEncrypt),  CCAlgorithm(kCCAlgorithmAES),  options,  keyBytes, keyLength,  cryptBytes,  dataBytes, data.count,  cryptBytes+kCCBlockSizeAES128, cryptLength,  &numBytesEncrypted) }        }    }    if UInt32(cryptStatus) == UInt32(kCCSuccess) {        cryptData.count = numBytesEncrypted + ivSize    }    else {        throw AESError.CryptorError(("Encryption failed", Int(cryptStatus)))    }    return cryptData;}// The iv is prefixed to the encrypted datafunc aesCBCDecrypt(data:Data, keydata:Data) throws -> Data? {    let keyLength = keyData.count    let validKeyLengths = [kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256]    if (validKeyLengths.contains(keyLength) == false) {        throw AESError.KeyError(("Invalid key length", keyLength))    }    let ivSize = kCCBlockSizeAES128;    let clearLength = size_t(data.count - ivSize)    var clearData = Data(count:clearLength)    var numBytesDecrypted :size_t = 0    let options   = CCOptions(kCCOptionPKCS7Padding)    let cryptStatus = clearData.withUnsafeMutableBytes {cryptBytes in        data.withUnsafeBytes {dataBytes in keyData.withUnsafeBytes {keyBytes in     CCCrypt(CCOperation(kCCDecrypt),  CCAlgorithm(kCCAlgorithmAES128),  options,  keyBytes, keyLength,  dataBytes,  dataBytes+kCCBlockSizeAES128, clearLength,  cryptBytes, clearLength,  &numBytesDecrypted) }        }    }    if UInt32(cryptStatus) == UInt32(kCCSuccess) {        clearData.count = numBytesDecrypted    }    else {        throw AESError.CryptorError(("Decryption failed", Int(cryptStatus)))    }    return clearData;}

用法示例:

let clearData = "clearData0123456".data(using:String.Encoding.utf8)!let keyData   = "keyData890123456".data(using:String.Encoding.utf8)!print("cleardata:   (clearData as NSData)")print("keydata:     (keyData as NSData)")var cryptdata:Data?do {    cryptData = try aesCBCEncrypt(data:clearData, keydata:keyData)    print("cryptdata:   (cryptData! as NSData)")}catch (let status) {    print("Error aesCBCEncrypt: (status)")}let decryptdata:Data?do {    let decryptData = try aesCBCDecrypt(data:cryptData!, keydata:keyData)    print("decryptdata: (decryptData! as NSData)")}catch (let status) {    print("Error aesCBCDecrypt: (status)")}

示例输出:

cleardata:   <636c6561 72446174 61303132 33343536>keydata:     <6b657944 61746138 39303132 33343536>cryptdata:   <92c57393 f454d959 5a4d158f 6e1cd3e7 77986ee9 b2970f49 2bafcf1a 8ee9d51a bde49c31 d7780256 71837a61 60fa4be0>decryptdata: <636c6561 72446174 61303132 33343536>

注意:
CBC模式示例代码的一个典型问题是它将创建和共享随机IV留给用户。该示例包括IV的生成,为加密数据添加前缀并在解密期间使用带前缀的IV。这使临时用户摆脱了CBC模式所需的详细信息。

为了安全起见,加密的数据也应具有身份验证,此示例代码未提供此身份验证以使其较小并允许与其他平台更好的互操作性。

还缺少从密码派生密钥的密钥,建议使用PBKDF2,因为文本密码用作密钥材料。

有关可靠的生产就绪多平台加密代码,请参见RNCryptor。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/426960.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号