Swift 中的异步加密
Asynchronous encryption in Swift
我正在尝试使用 Public/Private 密钥系统加密字符串。我需要将一个字符串传递给服务器,PHP 脚本可以在其中对其进行解密。我有一个工作的 JavaScript 到 PHP 脚本系统,但是,我想让 PHP 脚本也可以接受来自 iOS 应用程序的数据。任何人都可以指出我正确的方向,或者甚至可以向我介绍一个可以达到类似结果的系统。我正在寻找可以使用 PHP 解密的任何类型的加密。先感谢您。
也许你可以使用 openssl 库来 encrypt/decrypt RSA。
它在 iOS 和 PHP 中都存在。
如果您想以安全的方式发送字符串,使用安全层 (SSL/TLS) 就足够了,正如 Zaph 所说。
PHP和iOS都支持AES加密。
On iOS Common Crypto 同时支持非对称 (RSA) 和对称 (AES) 加密。如果没有 令人信服的 需要 PKI(Public 密钥基础设施),请使用 AES。
唯一的问题是 PHP 使用非标准填充(null)而不是 PKCS#7,因此您必须在 iOS 大小上进行自己的填充以匹配 Bozo scheme PHP 在 PHP 端使用 or 来匹配标准 PKCS#7。请注意,如果数据的最后一个字节为 0,PHP 填充将失败。
这是一个包含在带有 iv 的函数中的实现示例:
Swift 2.0
Add the Security.framework
to the project.
#import <CommonCrypto/CommonCrypto.h
func testCrypt(data:NSData, keyData:NSData, ivData:NSData, operation:CCOperation) -> NSData? {
let keyBytes = UnsafePointer<UInt8>(keyData.bytes)
print("keyLength = \(keyData.length), keyData = \(keyData)")
let ivBytes = UnsafePointer<UInt8>(ivData.bytes)
print("ivLength = \(ivData.length), ivData = \(ivData)")
let dataLength = Int(data.length)
let dataBytes = UnsafePointer<UInt8>(data.bytes)
print("dataLength = \(dataLength), data = \(data)")
let cryptData: NSMutableData! = NSMutableData(length: Int(dataLength) + kCCBlockSizeAES128)
let cryptPointer = UnsafeMutablePointer<UInt8>(cryptData.mutableBytes)
let cryptLength = size_t(cryptData.length)
let keyLength = size_t(kCCKeySizeAES128)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
let options: CCOptions = UInt32(kCCOptionPKCS7Padding)
var numBytesEncrypted :size_t = 0
let cryptStatus = CCCrypt(operation,
algoritm,
options,
keyBytes, keyLength,
ivBytes,
dataBytes, dataLength,
cryptPointer, cryptLength,
&numBytesEncrypted)
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.length = Int(numBytesEncrypted)
print("cryptLength = \(numBytesEncrypted), cryptData = \(cryptData)")
} else {
print("Error: \(cryptStatus)")
}
return cryptData;
}
// 测试代码:
let keyString = "!Use a data key!"
let keyData = (keyString as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
let ivString = "Use a random iv!"
let ivData = (keyString as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
let message = "Don´t try to read this text. Top Secret Stuff"
let data = (message as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
print("data: \(data)")
if let encryptedData = testCrypt(data, keyData:keyData, ivData:ivData, operation:UInt32(kCCEncrypt)) {
print("encryptedData: \(encryptedData)")
if let decryptedData = testCrypt(encryptedData, keyData:keyData, ivData:ivData, operation:UInt32(kCCDecrypt)) {
print("decryptedData: \(decryptedData)")
}
}
输出:
data: 446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666
keyLength = 16, keyData = 21557365 20612064 61746120 6b657921
ivLength = 16, ivData = 21557365 20612064 61746120 6b657921
dataLength = 46, data = 446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666
cryptLength = 48, cryptData = c184cb8b 3d24b56f 1e2896c4 a933a824 d5f8820b 9e7549c6 4188594c 8c1e5941 67adbc80 420bc362 0d851d4f f88d6675
encryptedData: c184cb8b 3d24b56f 1e2896c4 a933a824 d5f8820b 9e7549c6 4188594c 8c1e5941 67adbc80 420bc362 0d851d4f f88d6675
keyLength = 16, keyData = 21557365 20612064 61746120 6b657921
ivLength = 16, ivData = 21557365 20612064 61746120 6b657921
dataLength = 48, data = c184cb8b 3d24b56f 1e2896c4 a933a824 d5f8820b 9e7549c6 4188594c 8c1e5941 67adbc80 420bc362 0d851d4f f88d6675
cryptLength = 46, cryptData = 446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666
decryptedData: 446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666
SO 上还有 Swift AES 加密的其他示例。
ECB 示例 包装在一个函数中,但您应该真正使用 CBC 模式。
CBC 示例 SO answer 代码。
我正在尝试使用 Public/Private 密钥系统加密字符串。我需要将一个字符串传递给服务器,PHP 脚本可以在其中对其进行解密。我有一个工作的 JavaScript 到 PHP 脚本系统,但是,我想让 PHP 脚本也可以接受来自 iOS 应用程序的数据。任何人都可以指出我正确的方向,或者甚至可以向我介绍一个可以达到类似结果的系统。我正在寻找可以使用 PHP 解密的任何类型的加密。先感谢您。
也许你可以使用 openssl 库来 encrypt/decrypt RSA。
它在 iOS 和 PHP 中都存在。
如果您想以安全的方式发送字符串,使用安全层 (SSL/TLS) 就足够了,正如 Zaph 所说。
PHP和iOS都支持AES加密。
On iOS Common Crypto 同时支持非对称 (RSA) 和对称 (AES) 加密。如果没有 令人信服的 需要 PKI(Public 密钥基础设施),请使用 AES。
唯一的问题是 PHP 使用非标准填充(null)而不是 PKCS#7,因此您必须在 iOS 大小上进行自己的填充以匹配 Bozo scheme PHP 在 PHP 端使用 or 来匹配标准 PKCS#7。请注意,如果数据的最后一个字节为 0,PHP 填充将失败。
这是一个包含在带有 iv 的函数中的实现示例:
Swift 2.0
Add the
Security.framework
to the project.
#import <CommonCrypto/CommonCrypto.h
func testCrypt(data:NSData, keyData:NSData, ivData:NSData, operation:CCOperation) -> NSData? {
let keyBytes = UnsafePointer<UInt8>(keyData.bytes)
print("keyLength = \(keyData.length), keyData = \(keyData)")
let ivBytes = UnsafePointer<UInt8>(ivData.bytes)
print("ivLength = \(ivData.length), ivData = \(ivData)")
let dataLength = Int(data.length)
let dataBytes = UnsafePointer<UInt8>(data.bytes)
print("dataLength = \(dataLength), data = \(data)")
let cryptData: NSMutableData! = NSMutableData(length: Int(dataLength) + kCCBlockSizeAES128)
let cryptPointer = UnsafeMutablePointer<UInt8>(cryptData.mutableBytes)
let cryptLength = size_t(cryptData.length)
let keyLength = size_t(kCCKeySizeAES128)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
let options: CCOptions = UInt32(kCCOptionPKCS7Padding)
var numBytesEncrypted :size_t = 0
let cryptStatus = CCCrypt(operation,
algoritm,
options,
keyBytes, keyLength,
ivBytes,
dataBytes, dataLength,
cryptPointer, cryptLength,
&numBytesEncrypted)
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.length = Int(numBytesEncrypted)
print("cryptLength = \(numBytesEncrypted), cryptData = \(cryptData)")
} else {
print("Error: \(cryptStatus)")
}
return cryptData;
}
// 测试代码:
let keyString = "!Use a data key!"
let keyData = (keyString as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
let ivString = "Use a random iv!"
let ivData = (keyString as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
let message = "Don´t try to read this text. Top Secret Stuff"
let data = (message as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
print("data: \(data)")
if let encryptedData = testCrypt(data, keyData:keyData, ivData:ivData, operation:UInt32(kCCEncrypt)) {
print("encryptedData: \(encryptedData)")
if let decryptedData = testCrypt(encryptedData, keyData:keyData, ivData:ivData, operation:UInt32(kCCDecrypt)) {
print("decryptedData: \(decryptedData)")
}
}
输出:
data: 446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666 keyLength = 16, keyData = 21557365 20612064 61746120 6b657921 ivLength = 16, ivData = 21557365 20612064 61746120 6b657921 dataLength = 46, data = 446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666 cryptLength = 48, cryptData = c184cb8b 3d24b56f 1e2896c4 a933a824 d5f8820b 9e7549c6 4188594c 8c1e5941 67adbc80 420bc362 0d851d4f f88d6675 encryptedData: c184cb8b 3d24b56f 1e2896c4 a933a824 d5f8820b 9e7549c6 4188594c 8c1e5941 67adbc80 420bc362 0d851d4f f88d6675 keyLength = 16, keyData = 21557365 20612064 61746120 6b657921 ivLength = 16, ivData = 21557365 20612064 61746120 6b657921 dataLength = 48, data = c184cb8b 3d24b56f 1e2896c4 a933a824 d5f8820b 9e7549c6 4188594c 8c1e5941 67adbc80 420bc362 0d851d4f f88d6675 cryptLength = 46, cryptData = 446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666 decryptedData: 446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666
SO 上还有 Swift AES 加密的其他示例。
ECB 示例
CBC 示例 SO answer 代码。