【问题标题】:how to sign the byte array with SHA256withRSA having custom private key in Swift iOS如何在 Swift iOS 中使用具有自定义私钥的 SHA256withRSA 对字节数组进行签名
【发布时间】:2021-12-01 05:14:06
【问题描述】:

我有一个字节数组,想用 Swift 代码中的非对称私钥对其进行签名。我在下面有 java 代码,想在 iOS swift 中做同样的事情。

           try {

                final java.security.Signature instance = provider == null ?
                        java.security.Signature.getInstance(algorithm.getJvmName()) :
                        java.security.Signature.getInstance(algorithm.getJvmName(), provider);
                if (signature.getParameterSpec() != null) {
                    instance.setParameter(signature.getParameterSpec());
                }
                instance.initSign(key);
                instance.update(signingStringBytes);
                return instance.sign();

            } catch (final NoSuchAlgorithmException e) {

                throw new UnsupportedAlgorithmException(algorithm.getJvmName());

            } catch (final Exception e) {

                throw new IllegalStateException(e);
            }

在 Swift 中尝试了以下代码

public func sign(value: String, base64EncodingOptions:Data.Base64EncodingOptions = []) -> String?    {
    do {
        let keyData = Data(base64Encoded: privateKey)!
        let key = SecKeyCreateWithData(keyData as CFData,
                                       [kSecAttrKeyType: kSecAttrKeyTypeRSA,
                                       kSecAttrKeyClass: kSecAttrKeyClassPrivate,] as NSDictionary, nil)!

        var data = value.data(using: .utf8)!
        var error: Unmanaged<CFError>?
        guard let signedData = SecKeyCreateSignature(key,                                                       .rsaSignatureDigestPSSSHA256,                                                         data as CFData,                                                         &error) as Data?
        else {
            return nil
        }
        let signData = signedData as Data
        let signedString = signData.base64EncodedString(options: [])            

        return signedString
    }
    catch {
        //handle error
    }
    return ""
}

【问题讨论】:

  • 好的。您查看过 iOS SDK 的哪些部分并尝试过哪些内容?在 Developer.apple.com 上快速搜索会发现一个名为“Apple CryptoKit”的 SDK。也许这会给你一个开始寻找的好地方。
  • 更新了我的问题
  • 那段代码哪里出错了?当你运行它时会发生什么。我至少注意到SecKeyCreateWithData 的文档指出kSecAttrKeySizeInBits 属性是必需的。
  • @ScottThompson CryptoKit 不支持 RSA,如果这是他们使用的密钥。对于 Sandeep:一个好主意是在创建密钥时捕获变量中的错误,看看是否可以使用它。不幸的是,安全框架仍然有点老,所以它没有do/try/catch

标签: ios swift encryption cryptography


【解决方案1】:

我正在使用这种方法来签署会话密钥:

func signature(sessionKeyBase64: String, privateKey: String) throws -> String? {
    let sk = try extractSessionKey(encryptedSessionKeyBase64: sessionKeyBase64)
    let privateKeyDer = try SwKeyConvert.PrivateKey.pemToPKCS1DER(privateKey)
    let signature = try? CC.RSA.sign(sk, derKey: privateKeyDer, padding: .pkcs15, digest: .sha256, saltLen: 0);
    return signature?.base64EncodedString()
}

func extractSessionKey(encryptedSessionKeyBase64: String, privateKey: String) throws -> Data {
    let privateKeyDer = try SwKeyConvert.PrivateKey.pemToPKCS1DER(privateKey)
    let encryptedData = Data(base64Encoded: encryptedSessionKeyBase64)!
    return try CC.RSA.decrypt(encryptedData, derKey: privateKeyDer, tag: Data(), padding: .pkcs1, digest: .sha1).0
}

以及以下检查签名的方法:

func isVerified(encryptedKeyBase64: String, signatureBase64: String, signerPublicKeyBase64: String) throws -> Bool {
    let sk = try extractSessionKey(encryptedSessionKeyBase64: encryptedKeyBase64)
    let pk = try SwKeyConvert.PublicKey.pemToPKCS1DER(signerPublicKeyBase64)
    let signatureBytes = Data(base64Encoded: signatureBase64)
    return (try? CC.RSA.verify( sk, derKey: pk, padding: .pkcs15, digest: .sha256, saltLen: 0, signedData: signatureBytes!))!
}

借助第三方库SwCrypt

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-12
    • 1970-01-01
    • 1970-01-01
    • 2014-01-13
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多