首页 > 解决方案 > 在 iOS 中生成与 Android 相同的 RSA 密钥对和签名

问题描述

我想生成 RSA 密钥对,然后使用 RSA 私钥和我的有效负载生成签名 SHA256RSA。然后将签名和公钥提交给java后端。Java 使用我的公钥和签名并解密我的有效负载。我想在 iOS swift 中做到这一点。

这是我等效的 Android 代码。我需要一些类似的 iOS swift 解决方案。

import java.security.*  
import java.security.spec.PKCS8EncodedKeySpec.  
import java.security.spec.X509EncodedKeySpec.  
import java.util.*  
import javax.crypto.Cipher

//Code for generating RSA Key pair  
fun generateKeyPair(): Map<String, String>? {  
        val keys: MutableMap<String, String> = HashMap()  
        var b64PublicKey = ""  
        var b64PrivateKey = ""  
        val keyGen: KeyPairGenerator  
        try {  
            keyGen = KeyPairGenerator.getInstance("RSA")  
            keyGen.initialize(1024)  
            val keyPair = keyGen.genKeyPair()  
            val publicKey = keyPair.public.encoded   
            b64PublicKey = Base64.encodeToString(publicKey, Base64.DEFAULT)  
            val privateKey = keyPair.private.encoded  
            b64PrivateKey = Base64.encodeToString(privateKey, Base64.DEFAULT)  
        } catch (e: NoSuchAlgorithmException) {  
            e.printStackTrace()  
        }  
        keys["publicKey"] = b64PublicKey  
        keys["privateKey"] = b64PrivateKey  
        Log.d("Base public and private", keys.toString())  
        return keys  
    }  
    
//Code for generating Signature  
fun signSHA256RSA(input: String, strPk: String): String? {  
    try {  
        val b1: ByteArray = decode(strPk, Base64.DEFAULT)  
        val spec = PKCS8EncodedKeySpec(b1)  
        val kf: KeyFactory = KeyFactory.getInstance("RSA")  
        val privateSignature: Signature = Signature.getInstance("SHA256withRSA")  
        privateSignature.initSign(kf.generatePrivate(spec))  
        privateSignature.update(input.toByteArray(charset("UTF-8")))  
        val s: ByteArray = privateSignature.sign()  
        return Base64.encodeToString(s, Base64.DEFAULT)  
    }​​​​​​​​catch (e:Exception) {  
        e.printStackTrace()  
        Log.d("RAS Exception", e.printStackTrace().toString())  
    }  
    return ""  
}  

我已经尝试过使用这个 iOS 代码。但是 java 服务器不接受此代码生成的签名。并且java服务器接受Android生成的签名。

import Security

@available(iOS 10.0, *)  
class RSAGenerator   
{  
    private var publicKey : SecKey?   
    private var privateKey : SecKey?  
     
    //code for generating RSA key pair
    func generateKeys()  -> String?
    {
        var publicKeyString : String?
        var privateKeyString : String?

        //generate a new keypair
        let parameters : [String : AnyObject] =
        [
            kSecAttrKeyType as String : kSecAttrKeyTypeRSA,
            kSecAttrKeySizeInBits as String : 1024 as AnyObject,
        ]
        let status = SecKeyGeneratePair(parameters as CFDictionary, &publicKey, &privateKey)
        let status1 = SecKeyGeneratePair(parameters as CFDictionary, &publicKey, &privateKey)

        //---Save your key here--- //
         
        //Convert the SecKey object into a representation that we can send over the network
        if status == noErr && publicKey != nil
        {
            if let cfData = SecKeyCopyExternalRepresentation(publicKey!, nil)
            {
                let data = cfData as Data
                publicKeyString = data.base64EncodedString()
            }
        }
        
        
        if status1 == noErr && privateKey != nil
        {
            if let cfData = SecKeyCopyExternalRepresentation(privateKey!, nil)
            {
                let data = cfData as Data
                privateKeyString = data.base64EncodedString()
                print(privateKeyString)

            }
        }
        
         
        print(publicKeyString)
        return publicKeyString
    }
     
    //code for generating signature
    func generateSignature(_ string : String) -> String?
    {
        var signature : String?
         
        let fileData = Data(string.utf8) //kSecPaddingNone
        
            if (privateKey != nil)
            {
                //hash the message first
                let digestLength = Int(CC_SHA256_DIGEST_LENGTH)
                let hashBytes = UnsafeMutablePointer<UInt8>.allocate(capacity: digestLength)
                CC_SHA256([UInt8](fileData), CC_LONG(fileData.count), hashBytes)
                 
                //sign
                let blockSize = SecKeyGetBlockSize(privateKey!) //in the case of RSA, modulus is the same as the block size
                var signatureBytes = [UInt8](repeating:0, count:blockSize)
                var signatureDataLength = blockSize
                let status = SecKeyRawSign(privateKey!, .PKCS1SHA256, hashBytes, digestLength, &signatureBytes, &signatureDataLength)
                if status == noErr
                {
                    let data = Data(bytes: signatureBytes, count: signatureDataLength)
                    signature = data.base64EncodedString()
                }
            }
        print(signature)

        return signature
    }
    
}

    

我正在为我在 swift iOS 中的代码寻找类似 Android 的解决方案。
提前致谢!

标签: javaandroidiosswift

解决方案


推荐阅读