【问题标题】:How to Decoding AES-128 Data in iOS如何在 iOS 中解码 AES-128 数据
【发布时间】:2021-04-16 15:34:07
【问题描述】:

我正在与需要加密的设备交换数据。根据说明,我的 iOS 应用会生成一个 RSA 2048 位公钥-私钥对,然后我将公钥发送给设备。

我使用带有openssl 的 macOS 命令行创建了公钥-私钥对(因为我不知道如何让 iOS 做到这一点 - 但这是一个未来的问题):

openssl req -x509 -newkey rsa:2048 -out cert.pem

openssl x509 -in cert.pem -noout -pubkey

我将cert.pem 中的值以及私钥和公钥复制到我的应用程序中:

let certificate = "MIIDej....GWB"

let privateKey = "MIIFhz...Q=="

let publicKey = "MIIBI...AQAB"

当我向设备发送公钥时,设备会很高兴并以 AES-128 格式发回使用我发送的公钥加密的数据。

我在我的头上,但我是试图让这个设备工作的人。

有没有办法使用我在我的应用中设置为Strings 的私钥或证书来解码来自设备的数据?

我一直在查看 Security 和 CryptoKit 文档,它让我头晕目眩。

FWIW,我能够在 cert.pem 文件中的字符串集上使用 SecCertificateCreateWithData 并阅读其一些信息,例如摘要。但我不知道如何应用私钥或使用证书来解码数据。我需要像 Dummies 的悬崖笔记之类的东西。

谢谢。

【问题讨论】:

  • “发回使用公钥加密的 AES-128 数据”是不可能的。 AES 不使用公钥。它使用完全不同的对称密钥。没有单一的标准方法来实现您所描述的内容(有几个官方标准,但许多系统都是临时的)。处理这个问题的正确方法很大程度上取决于服务器实现的确切协议。理想情况下,您有一个文档来描述它。如果没有,那么完整的服务器代码。 (不幸的是,实施临时协议通常需要咨询而不是 Stack Overflow 问题。)
  • 谢谢。我刚刚粘贴了我收到的文档中所述的内容。我将尝试找到作者并从那里开始工作。谢谢。

标签: ios swift security openssl


【解决方案1】:

Apple documentation 描述如何在 iOS 端生成密钥对。

示例:

let tag = "com.example.keys.mykey".data(using: .utf8)!
let attributes: [String: Any] =
    [kSecAttrKeyType as String:            kSecAttrKeyTypeRSA,
     kSecAttrKeySizeInBits as String:      2048,
     kSecPrivateKeyAttrs as String:
        [kSecAttrIsPermanent as String:    true,
         kSecAttrApplicationTag as String: tag]
]

var publicKey: SecKey?
var privateKey: SecKey?
        
SecKeyGeneratePair(attributes, &publicKey, &privateKey)

更多属性可用here

然后您可以使用以下方法获取私钥或公钥的外部表示: SecKeyCopyExternalRepresentation.

示例:

var error: Unmanaged<CFError>?
SecKeyCopyExternalRepresentation(secKey, &error) as Data?

要解密 AES-128 数据,您需要使用 CCCryptHere 您有来自 Apple 的示例支持数据如何加密,但要解密数据,您需要将第一个参数更改为 kCCDecrypt

示例:

extern NSData * SecDecryptAES128CBCPad(NSData * data, NSData * key, NSData * iv) {
    CCCryptorStatus    err;
    NSMutableData *    result;
    size_t              resultLength;

    NSCParameterAssert(key.length == kCCKeySizeAES128);
    NSCParameterAssert(iv.length == kCCBlockSizeAES128);

    // Padding can expand the data, so we have to allocate space for that.  The rule for block
    // cyphers, like AES, is that the padding only adds space on encryption (on decryption it
    // can reduce space, obviously, but we don't need to account for that) and it will only add
    // at most one block size worth of space.

    result = [[NSMutableData alloc] initWithLength:[data length] + kCCBlockSizeAES128];

    err = CCCrypt(
        kCCDecrypt,
        kCCAlgorithmAES128,
        kCCOptionPKCS7Padding,
        key.bytes, key.length,
        iv.bytes,
        data.bytes, data.length,
        result.mutableBytes,  result.length,
        &resultLength
    );
    assert(err == kCCSuccess);

    // Set the output length to the value returned by CCCrypt.  This is necessary because
    // we have padding enabled, meaning that we might have allocated more space than we needed.

    [result setLength:resultLength];

    return result;
}

CCCrypt 方法中的参数(如kCCOptionPKCS7Paddingiv)您需要根据您的示例进行调整。

【讨论】:

  • 感谢解密提示。生成密钥对不适用于此设备。有人告诉我我需要 PKCS8 和 X509 密钥。设备无法识别SecKeyGeneratePair 生成的公钥,这就是我求助于通过openssl 寻找 macOS 解决方案的原因。我一直在阅读 iOS 是出了名的难以与需要加密数据交换的非 Apple 服务一起使用。但是,我会尝试查看您的解决方案是否适用于设备返回的数据。谢谢。
  • @P.Ent 但请记住,在代码中使用私钥作为纯字符串存在安全风险(当应用程序公开可用时),因为使用逆向工程很容易从二进制文件中获取它。例如,Hopper Disassembler 是免费提供的,当二进制文件加载到该程序中时,所有字符串都将从您的代码中排除并显示。
  • 我同意。由于我无法弄清楚如何让 iOS 生成该设备可接受的公钥,因此我将它们作为字符串放在应用程序中,只是为了进入下一步,即对来自设备的数据进行编码/解码。但我不知道我在做什么,但我被分配去做这项工作。我只想知道我是否可以使用这些纯字符串。如果没有,除了获得密码学学位之外,我不知道该怎么做。
  • 是的,因为正如 SecKeyCopyExternalRepresentation 文档中所述,它返回 PKCS #1 格式。因此,您需要找到将其转换为 PKCS8 的解决方案。 Here 你有 rfc 文档这种格式应该是什么样子,还有一个苹果论坛上的 thread
猜你喜欢
  • 2013-12-07
  • 1970-01-01
  • 1970-01-01
  • 2020-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-29
相关资源
最近更新 更多