【问题标题】:Asynchronous encryption in SwiftSwift 中的异步加密
【发布时间】:2015-05-27 04:11:22
【问题描述】:

我正在尝试使用公钥/私钥系统加密字符串。我需要将一个字符串传递给服务器,PHP 脚本可以在其中解密它。我有一个可以工作的 JavaScript 到 PHP 脚本系统,但是,我想让 PHP 脚本也可以接受来自 iOS 应用程序的数据。谁能指出我正确的方向,或者甚至可以向我介绍一个可以达到类似结果的系统。我正在寻找可用于通过 PHP 解密的任何类型的加密。先感谢您。

【问题讨论】:

  • 我知道如何传递字符串,我只需要加密它。
  • 您能否添加有关您想要哪种加密的详细信息?比如GPG?
  • 为什么选择“公钥/私钥系统”,而不仅仅是 AES(高级加密标准)等对称加密。或者只使用使用 PKI 和对称加密的 SSL/TLS (https)。

标签: php ios swift encryption


【解决方案1】:

PHP 和 iOS 都支持 AES 加密。

在 iOS 上,Common Crypto 支持非对称 (RSA) 和对称 (AES) 加密。如果对 PKI(公钥基础设施)没有强制需求,请使用 AES。

唯一的问题是 PHP 使用非标准填充 (null) 而不是 PKCS#7,因此您必须在 iOS 大小上进行自己的填充以匹配 PHP 使用的 Bozo 方案或在 PHP 端进行匹配标准 PKCS#7。请注意,如果数据的最后一个字节为 0,则 PHP 填充失败。

这是一个用 iv 包裹在函数中的实现示例:

斯威夫特 2.0

将Security.framework 添加到项目中。

#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)")
    }
}

输出:

数据:446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666 密钥长度 = 16,密钥数据 = 21557365 20612064 61746120 6b657921 ivLength = 16,ivData = 21557365 20612064 61746120 6b657921 数据长度 = 46,数据 = 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 加密数据:c184cb8b 3d24b56f 1e2896c4 a933a824 d5f8820b 9e7549c6 4188594c 8c1e5941 67adbc80 420bc362 0d851d4f f88d6675 密钥长度 = 16,密钥数据 = 21557365 20612064 61746120 6b657921 ivLength = 16,ivData = 21557365 20612064 61746120 6b657921 数据长度 = 48,数据 = 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 解密数据:446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666

在 SO 上还有其他 Swift AES 加密示例。

ECB 示例 SO answer 包装在一个函数中,但您应该真正使用 CBC 模式。

CBC 示例SO answer 代码。

【讨论】:

  • 谢谢,我想我可以用这个运行。
【解决方案2】:

您可能可以使用 openssl 库来加密/解密 RSA。

它在 iOS 和 PHP 中都存在。

如果您想以安全的方式发送字符串,如 Zaph 所说,使用安全层 (SSL/TLS) 就足够了。

【讨论】:

  • RSA 是我在网站部分使用的,我现在更喜欢使用它。我一直无法找到快速实现它的工作示例。如果您有任何建议,我将不胜感激。
  • 在 iOS 和 OSX 上,必须从源代码编译 OpenSSL 库。 Common Crypto 支持非对称 (RSA) 和对称 (AES) 加密。如果没有对 PKI 的迫切需求,请使用 AES。请记住,RSA 数据大小仅限于密钥大小,对称加密没有限制。通常的情况是使用对称密码对数据进行加密,然后使用非对称加密对对称密钥进行加密。
猜你喜欢
  • 1970-01-01
  • 2019-01-10
  • 2015-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 2017-04-16
相关资源
最近更新 更多