美文网首页
Swift RSA 加签验签

Swift RSA 加签验签

作者: __Simon__ | 来源:发表于2020-04-13 17:52 被阅读0次

    Mac 终端生成密钥

    • 生成私钥
    openssl genrsa -out rsa_private_key.pem 2048
    
    • 生成公钥
    openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
    
    • 生成证书
    openssl req -new -key rsa_private_key.pem -out certificate.csr
    

    生成的密钥字符串

    struct RSAKey {
        static let privateKey = """
        -----BEGIN RSA PRIVATE KEY-----
        MIIEowIBAAKCAQEAtxt4MWNQdHp3FE03wHNoyAV63vvuOG47ToObtu9Z2ik6KQ1I
        rDfjOIjmD9P6F132Bw2VnkTy+zAXelnSYMiRcagTsXlGcI7SyG8dwc3aU12fgph0
        dBL5wIGWDVMqw6RJsEUYoV1ueaUCPiKr1jQGQpJ8Jlg04mj6glWx4G3mkvOc3nSq
        u915SANdR1BCgvJDhtRi4onLQcAUvRJOe8cEHhlAX6z45R8/yfkP9OMENAlchkQr
        2LUr3I7FSUl9q3pCFVmlRiML+IPySj3cqA6+8Gz2ZST8+8HfLCkcDC9e8AMZcJEx
        5sm0wk0TdFtl9o7SGAFcMR9CG9zWji7Z4SlA3QIDAQABAoIBAQCJ+JLadAEdo2Gy
        1HRb+RpNDYQGHULlFnptsNFWSIgl0MbYRAAsdHgsE0t3Rby+erh1nBDPDxkfmJ84
        PBI/hyHAyGr+YWloStYc3U1IyTnnczZMC2BETkAOhBZyt+YTQOmdfpMOk/44ftNv
        ymQ8pTrKUuJlajV/HKcWKkg72dPRiaPC/tCANZQLNjgylQUu3u1wEiCixBa+4lkO
        Uccldxy+7P9dzFTZJH/rBqxPCgHhajpSoBnFZJAC22Wk81QvRPS/JfbBG7wdxI7+
        iuxuH69bKHrZHPAxGpn0LqfsNvgJ5G/2jwyy/GkZDpNYsgjnKcAgyCsOCTNppO+J
        f5Ly6ljBAoGBAOmZmdeMkBxVPYOiKi37zJXwutvhKEos3I/jbTcaFnXaFpvP88vb
        XXnsy4bgFQ6Pm61ZMyguYO/Hn6LYjddDmM7C2yzWBIMFVnXMiTVtNUoXTbIH/8CC
        +Mz4O5ztITe1AU0D+aUzULGLjKv6LhEAAUYRAyrhR0y+BKNQYFyoHTRVAoGBAMiq
        YHEgvAqxlkDIh2hAVQce2PYTI0RJwBIPmK71H5j3JGZmda0JILqzLw176gV3k0Uq
        6wX65fD/psB683INy9fZ7fMGgbsnswDdqdBAUBdtPgzQO6fgEZ83S1FCKuceqHT5
        Wuj/hxeRvoE2+/tIYqWyM18oppFEoJxCF99izaJpAoGAFl+s2XVQFDah1qrAiXj1
        hmLxMsAlAL29PlbVDhMElbMWuUO4oQzYriXc9IUf3y4oBflmKfIPPMgM5ScCptyF
        lUAah/fTpMztFAlMFv7nvLnwqh2UBFdHBzK7WvNnXBONFVhNH+KDVw37ojkrElvC
        w3g7qm67SoFkplO7dwRvD6UCgYBux0A+s+ebr7ZXRV0bfIh0Sd9U2fPaOyzBy8Jq
        tAAhni6GKYJFaIidCVashwAGzKCMysi8oGpYxYn1MOs8x8kE/NaUF79+5se3bqfU
        w+xzQmfDAyIr51NTJl96GKE+vnoZOZ+qiYa2yEr3YrdxXeC3wM0Dd5mdENnp6cLs
        G8uSIQKBgEGR6KtnB2OOJObRfOCO3+asXoPP4kr4WnFeahvNOsKA+6FCYxljYX3J
        JemPi6eaZmIlXMqSgPjPjGNRv7vZbiCaROFdzXrgZbGuN7P2GLDI5Oq0fsfktd3y
        adXgXI4TPZ7/hw0o9Rpl63eIfaTxcCJM19VsNCWHdccF6LxTCewS
        -----END RSA PRIVATE KEY-----
        """
    
        static let publicKey = """
        -----BEGIN PUBLIC KEY-----
        MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtxt4MWNQdHp3FE03wHNo
        yAV63vvuOG47ToObtu9Z2ik6KQ1IrDfjOIjmD9P6F132Bw2VnkTy+zAXelnSYMiR
        cagTsXlGcI7SyG8dwc3aU12fgph0dBL5wIGWDVMqw6RJsEUYoV1ueaUCPiKr1jQG
        QpJ8Jlg04mj6glWx4G3mkvOc3nSqu915SANdR1BCgvJDhtRi4onLQcAUvRJOe8cE
        HhlAX6z45R8/yfkP9OMENAlchkQr2LUr3I7FSUl9q3pCFVmlRiML+IPySj3cqA6+
        8Gz2ZST8+8HfLCkcDC9e8AMZcJEx5sm0wk0TdFtl9o7SGAFcMR9CG9zWji7Z4SlA
        3QIDAQAB
        -----END PUBLIC KEY-----
        """
    }
    

    RSAKey 结构体用来存储已经生成的私钥和公钥

    通过密钥字符串生成 SecKey,加签,验签

    • 详细代码
    import Foundation
    
    /// 密钥类型
    enum KeyType {
        case publicKey
        case privateKey
    }
    
    struct RSASigner {
    
        /// 通过密钥字符串获取 SecKey 类型的密钥
        /// - Parameter keyString: 密钥字符串
        /// - Parameter keyType: 密钥类型
        static func getSecKey(with keyString: String,keyType: KeyType) -> SecKey? {
            let strippedKey = String(keyString.filter { !" \n\t\r".contains($0) })
    
            let pemComponents = strippedKey.components(separatedBy: "-----")
    
            guard pemComponents.count >= 5 else { return nil }
    
            guard let keyData = Data(base64Encoded: pemComponents[2]) else { return nil }
    
            let keyClass = keyType == .publicKey ? kSecAttrKeyClassPublic : kSecAttrKeyClassPrivate
            let sizeInBits = keyData.count * MemoryLayout<UInt8>.size
            let keyDict: [CFString: Any] = [
                kSecAttrKeyType: kSecAttrKeyTypeRSA,
                kSecAttrKeyClass: keyClass,
                kSecAttrKeySizeInBits: NSNumber(value: sizeInBits)
            ]
    
            guard let key = SecKeyCreateWithData(keyData as CFData, keyDict as CFDictionary, nil) else { return nil }
    
            return key
        }
    
    
        /// 使用 RSA 算法签名
        /// - Parameter text: 明文
        /// - Parameter privateKey: 密钥
        static func sign(text: String, with privateKey: SecKey) -> String? {
            guard let data = text.data(using: .utf8) else { return nil }
    
            guard let signedData = SecKeyCreateSignature(privateKey, .rsaSignatureMessagePKCS1v15SHA256, data as CFData , nil) as Data? else { return nil }
    
            return signedData.base64EncodedString()
        }
    
    
        /// 验证签名
        /// - Parameter signature: 签名字符串
        /// - Parameter text: 明文
        /// - Parameter publicKey: 公钥
        static func verify(signature: String, text: String, with publicKey: SecKey) -> Bool {
            guard let signedData = text.data(using: .utf8) else { return false }
    
            guard let signature = Data(base64Encoded: signature) else {  return false }
    
            return SecKeyVerifySignature(publicKey, .rsaSignatureMessagePKCS1v15SHA256, signedData  as CFData, signature as CFData,nil)
        }
    }
    

    上面的代码可以通过 RSA 私钥字符串或公钥字符串(如上面所示)生成 Swift 中需要的 SecKey 类型的密钥。使用 SecKey 类型的私钥字符串用来加签,使用 SecKey 类型的公钥用来验签。

    定义了一个枚举类型 KeyType 用来标识要生成的是私钥(publicKey)还是公钥(privateKey

    使用 getSecKey(with,keyType)方法来获取 SecKey 类型的密钥

    使用 sign(text: with:) 方法类生成签名

    使用 verify(signature: text: with) 来验证签名是否正确

    • 使用示例
    func testSignAndVerify() {
        let text = "我是明文"
        guard let privateKey =  RSASigner.getSecKey(with: RSAKey.privateKey, keyType: .privateKey) else {
            return
        }
        guard let signature = RSASigner.sign(text: text, with: privateKey) else {
            return
        }
        guard let pubKey = RSASigner.getSecKey(with: RSAKey.publicKey, keyType: .publicKey) else {
            return
        }
        let result = RSASigner.verify(signature: signature, text: text, with: pubKey)
        print("明文:\(text)")
        print("签名:\(signature)")
        print("验签\(result ? "成功" : "失败")")
    }
    
    • 打印结果
    明文:我是明文
    签名:tD2TjObA/NBRfHjbd3wT4KyAuo+yMWiIXJHVA3qOYMP4ow/WJKzrtaSVQT/COt3ZNMhYY1MTn5syemJ3tcAcFvJtIyprN+rnJMLR9Yu8rrh5yfOa/t55pMsedobUt3ER7SCI5oosyVtvO0EojDK5SG1OFuT9GgfbnSNoFkf2blK7bnuEiLvnlSw/TukKusqeX2OiatvL1qtE3Z0b9RKZRaFl99o/pVo+D5vNGG+K5A9dt6vG/gI0OZYR9YZHT1GIOAryFBejRDeuqP3vniQL0AJRjYXr+cZ4LkiFV1w8X61+Qz6udD6pjeYou3kBwKJOF08mcu+ot9DIh508dQfUtw==
    验签成功
    

    相关文章

      网友评论

          本文标题:Swift RSA 加签验签

          本文链接:https://www.haomeiwen.com/subject/puunmhtx.html