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 結(jié)構(gòu)體用來存儲已經(jīng)生成的私鑰和公鑰
通過密鑰字符串生成 SecKey朵逝,加簽,驗簽
- 詳細(xì)代碼
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
用來標(biāo)識要生成的是私鑰(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 ? "成功" : "失敗")")
}
- 打印結(jié)果
明文:我是明文
簽名:tD2TjObA/NBRfHjbd3wT4KyAuo+yMWiIXJHVA3qOYMP4ow/WJKzrtaSVQT/COt3ZNMhYY1MTn5syemJ3tcAcFvJtIyprN+rnJMLR9Yu8rrh5yfOa/t55pMsedobUt3ER7SCI5oosyVtvO0EojDK5SG1OFuT9GgfbnSNoFkf2blK7bnuEiLvnlSw/TukKusqeX2OiatvL1qtE3Z0b9RKZRaFl99o/pVo+D5vNGG+K5A9dt6vG/gI0OZYR9YZHT1GIOAryFBejRDeuqP3vniQL0AJRjYXr+cZ4LkiFV1w8X61+Qz6udD6pjeYou3kBwKJOF08mcu+ot9DIh508dQfUtw==
驗簽成功