"""
-----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 {
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
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()
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==
复制代码