如何解决CryptoSwift-在iOS中将makeEncryptor用于少于16个字节的字符串时得到零
我正在使用cryptoSwift库进行加密和解密。但是它仅使用16个字节的字符串。如果我传递的是小字符串或少于16个字节,则结果为nil。
我正在使用Cryptor实例进行增量操作,并且一次加密/解密一个部分。
请在这里帮助我,我做错了什么吗?
谢谢。
loc_perc = 0.5
dfNew = df.assign(
temp=lambda x: x.Space,Reduced_Space=lambda x: np.where(x.Location == "Y",np.where((x.Space * dual_loc_perc) < x.Min,x.Space and x.Dual_Location ='',x.Space * dual_loc_perc),x.Space),).drop("temp",1)
解决方法
在CryptoSwift中实现aes-256-gcm
并没有错,正如一些评论者所建议的那样,您的代码中仅包含一些错误。希望以下内容能对您有所帮助。
为简便起见,我在下面将其称为GCM。
GCM加密将纯文本,密钥和初始化向量作为输入,并生成密文和身份验证标签。在您的代码中,将身份验证标签设置为随机字节,从而覆盖身份验证标签。
我认为,如果将代码分解为一些功能,每个功能都有明确的定义,这会更清楚一些。为了清楚起见,我还剥离了从Data
到[UInt8]
的一些转换。
这是加密功能的样子:
func enc(plainText: [String],key: [UInt8],iv: [UInt8]) throws -> (cipherText: [UInt8],authenticationTag: [UInt8]?)
{
let gcmEnc = GCM(iv: iv,mode: .detached)
var enc = try AES(key: key,blockMode: gcmEnc,padding: .noPadding).makeEncryptor()
var ciphertext = Array<UInt8>()
for txt in plainText {
ciphertext += try enc.update(withBytes: Array(txt.utf8))
}
ciphertext += try enc.finish()
return (ciphertext,gcmEnc.authenticationTag)
}
解密GCM时,您需要输入密文,密钥,初始化向量和身份验证标签。看起来像这样:
func dec(cipherText: [UInt8],authenticationTag: [UInt8]?,iv: [UInt8]) throws -> [UInt8]? {
let tagLength = authenticationTag?.count ?? 0
let gcmDec = GCM.init(iv: iv,additionalAuthenticatedData: nil,tagLength: tagLength,mode: .detached)
gcmDec.authenticationTag = authenticationTag
var aesDec = try AES(key: key,blockMode: gcmDec,padding: .noPadding).makeDecryptor()
var decData = try aesDec.update(withBytes: cipherText)
decData += try aesDec.finish()
return decData
}
在两种情况下,都需要确保将finish
调用的输出附加到密文或纯文本中。这对于少量数据尤为重要,因为update
方法可能不会产生任何结果!
编写了这两个函数后,您可以按以下方式重写测试函数:
func encAndDec(){
do {
guard let key = Data.init(base64Encoded: "12345678901234567890123456789012".base64Encoded()!)
else {
fatalError("Failed to create key")
}
let iv : Array<UInt8> = [0,0]
//let arrStr = ["My name is tarun"] // Working
let arrStr = ["tarun"] // Not working for this string
let (cipherText,authenticationTag) = try enc(plainText: arrStr,key: key.bytes,iv: iv)
guard let decrypedPlainText = try dec(cipherText: cipherText,authenticationTag: authenticationTag,iv: iv) else {
fatalError("Decryption return nil")
}
guard let decryptedString = String(bytes: decrypedPlainText,encoding: .utf8) else {
fatalError("Failed to convert plaintext to string using UTF8 encoding.")
}
print("Decrypted Plaintext: \(decryptedString)")
}
catch let e {
print("EXCEPTION: \(e)")
}
}
如果运行此命令,则会发现它会产生预期的输出。
完整的示例代码可在以下位置找到:https://gist.github.com/iosdevzone/45456d2911bf2422bc4a6898876ba0ab
,我不认为GCM需要填充。这是直接来自NODE.JS文档的示例,可以很好地工作并且不使用填充。下面的行将显示密文长度为5
我对Ruby,Java,Go和其他代码也做了同样的事情,没有一个需要填充或输入值是16字节的倍数,就像Swift库似乎需要的那样。其他人可以帮助确认这是GCM的Swift实施中的错误吗?
const crypto = require('crypto');
const key = '12345678901234567890123456789012';
const iv = '000000000000'
const cipher = crypto.createCipheriv('aes-256-gcm',key,iv);
const plaintext = 'Hello';
const ciphertext = cipher.update(plaintext,'utf8');
**console.log("ciphertext length %d",ciphertext.length)**
cipher.final();
const tag = cipher.getAuthTag();
const decipher = crypto.createDecipheriv('aes-256-gcm',iv);
decipher.setAuthTag(tag);
const receivedPlaintext = decipher.update(ciphertext,null,'utf8');
try {
decipher.final();
} catch (err) {
console.error('Authentication failed!');
return;
}
console.log(receivedPlaintext);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。