简体   繁体   中英

how to sign the byte array with SHA256withRSA having custom private key in Swift iOS

I have a byte array and want to sign it with an Asymmetric private key in Swift code. I have java code below and want same thing in 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);
            }

Tried the below code in 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 ""
}

I am using this method to sign a session key:

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
}

and a below method to check a signature:

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!))!
}

with the help of the third party library SwCrypt

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM