我尝试用
创建自己的SecKeyexponent:
let exponent = "10001"
modulus:
let modulus = "D6250B831F82EC984513922E797283E4D3879E1F0AD52364EBDA5A5696F6E75CDCE0704A993F3F95AA557A6882A525EC4B8344DA3E7DFDECCBACCEF18131E461D3C5D3D7E1334C6AE27E5CDEF8A577857542BCBEF6CF021B0EE5604534E6C6CBAEFA6EFFC1AB93DEE7CE51A8C8F2B7345680BDF840841C3A6F654CD1F10BA2FD5CA1C6E782A8FAEC79BD22FA12116D75FFAEDB2DEC151E0B60DB91F2E74BA78EFBB45DF739AF9CDD41C482DC22FC76E03C8E2141BDAE5406C0DA230E2C7EFFC68C8811E1544496332B03BCFF0F627A8DF51D2E2B32B0771D1C6F87AD56010DCB7A3862C63B88B2CF7D7AD40CC53AF0CFEC0820777C9CCE95A58848D67779AE8D"
as publicKey加密Swift中的文本。有人能帮我吗?
这是我的代码:
import Foundation
import Security
class Encryption {
var publicKeyPtr, privateKeyPtr: Unmanaged<SecKey>?
var publicKey, privateKey: SecKey?
let parameters: [String:String] = [kSecAttrKeyType: kSecAttrKeyTypeRSA, kSecAttrKeySizeInBits: "2048"]
init(){
}
func genKey() {
let status = SecKeyGeneratePair(parameters, &publicKeyPtr, &privateKeyPtr)
publicKey = publicKeyPtr!.takeRetainedValue()
privateKey = privateKeyPtr!.takeRetainedValue()
}
func encrypt(plainText: String, publicKey: SecKey) -> [UInt8]{
let blockSize = SecKeyGetBlockSize(publicKey)
let plainTextData = [UInt8](plainText.utf8)
let plainTextDataLength = UInt(countElements( plainText))
var encryptedData = [UInt8](count: Int(blockSize), repeatedValue: 0)
var encryptedDataLength = blockSize
let result = SecKeyEncrypt(publicKey, SecPadding(kSecPaddingPKCS1),
plainTextData, plainTextDataLength, &encryptedData, &encryptedDataLength)
return encryptedData
}
func decrypt(data: [UInt8]) -> String{
let blockSize = SecKeyGetBlockSize(publicKey)
var decryptedData = [UInt8](count: Int(blockSize), repeatedValue: 0)
var decryptedDataLength = blockSize
let result = SecKeyDecrypt(privateKey, SecPadding(kSecPaddingPKCS1),
data, blockSize,
&decryptedData, &decryptedDataLength)
let decryptedText = String(bytes: decryptedData,
encoding:NSUTF8StringEncoding)
return decryptedText!
}
}
答案 0 :(得分:6)
对于仍在寻找答案的人,也许我可以提供帮助。
SecKeyCreateWithData
从iOS 10开始,您可以使用SecKeyCreateWithData
从该密钥的外部表示中创建SecKey
。
此表示的格式应与SecKeyCopyExternalRepresentation
返回的格式相同。正如docs中所讨论的那样,该格式是RSA密钥的PCKS#1。
因此,为了从给定的模数和指数创建SecKey
,我们需要获得该密钥的PKCS#1表示。
引自PKCS#1:
RSA公钥应使用ASN.1类型来表示 RSAPublicKey:
RSAPublicKey ::= SEQUENCE { modulus INTEGER, -- n publicExponent INTEGER -- e }
RSAPublicKey类型的字段具有以下含义:
- 模量是RSA模量n。
- publicExponent是RSA公共指数e。
此ASN.1类型需要使用DER表示,以获取SecKeyCreateWithData
期望的数据。
下面我将尝试讨论如何在Swift中获得所需的数据格式。请注意,您也可以使用命令行中的OpenSSL执行此操作,如果您只需要执行一次,这可能会更容易。
Ignacio Nieto Carvajal在this article中详细介绍了需要做的事情。
基本上,您需要将模数和指数编码为DER INTEGER,然后将它们组合在DER SEQUENCE中。
您可以找到一些有关如何执行此操作的代码here和here。 ( Disclamer:我是该图书馆的贡献者之一。)
我将在下面总结一下。
假设我们将RSA模数和公共指数作为字节数组。从模数和指数的不同表示中获取字节数组不应该太难。
let exponent: [UInt8] = [
1, 0, 1
]
var modulus: [UInt8] = [
136, 0, 243, 196, 194, 126, 151, 243, 72, 84, 246, 234, 207, 215, 168, 5, 233, 212, 8, 37, 34, 52, 215, 217, 223, 183, 58, 129, 66, 112, 88, 71, 201, 71, 33, 156, 132, 7, 189, 234, 110, 6, 46, 189, 233, 206, 61, 128, 220, 138, 56, 49, 34, 159, 245, 208, 214, 49, 169, 58, 170, 68, 127, 93, 137, 99, 74, 54, 65, 109, 112, 33, 65, 169, 246, 176, 128, 121, 171, 35, 214, 236, 210, 123, 94, 146, 86, 30, 134, 135, 116, 124, 4, 55, 208, 163, 219, 220, 203, 249, 107, 69, 147, 169, 66, 214, 179, 195, 152, 211, 209, 78, 100, 114, 209, 203, 120, 16, 254, 24, 39, 143, 79, 49, 202, 10, 37, 2, 155, 162, 14, 253, 194, 205, 74, 116, 60, 205, 25, 53, 85, 144, 72, 11, 7, 133, 78, 149, 111, 0, 215, 174, 36, 104, 175, 62, 196, 197, 49, 78, 172, 146, 82, 216, 160, 45, 48, 212, 50, 168, 208, 255, 205, 82, 22, 11, 13, 156, 197, 42, 159, 26, 124, 237, 178, 131, 239, 186, 37, 96, 24, 154, 243, 202, 252, 87, 102, 23, 19, 29, 73, 130, 95, 45, 219, 104, 13, 54, 30, 165, 144, 223, 1, 14, 169, 100, 111, 246, 54, 185, 47, 156, 238, 249, 88, 33, 244, 135, 233, 102, 36, 86, 196, 143, 178, 176, 62, 24, 178, 209, 163, 244, 116, 236, 81, 177, 190, 205, 140, 230, 6, 113, 158, 105, 111, 123
]
然后我们需要确保模数以0x00
为前缀indicate that it is a non-negative number。
modulus.insert(0x00, at: 0)
现在我们将模数和指数编码为INTEGERs。
var modulusEncoded: [UInt8] = []
modulusEncoded.append(0x02)
modulusEncoded.append(contentsOf: lengthField(of: modulus))
modulusEncoded.append(contentsOf: modulus)
var exponentEncoded: [UInt8] = []
exponentEncoded.append(0x02)
exponentEncoded.append(contentsOf: lengthField(of: exponent))
exponentEncoded.append(contentsOf: exponent)
var sequenceEncoded: [UInt8] = []
sequenceEncoded.append(0x30)
sequenceEncoded.append(contentsOf: lengthField(of: (modulusEncoded + exponentEncoded)))
sequenceEncoded.append(contentsOf: (modulusEncoded + exponentEncoded))
以下是一个辅助函数,用于计算上面使用的DER类型的长度字段:
func lengthField(of valueField: [UInt8]) -> [UInt8] {
var count = valueField.count
if count < 128 {
return [ UInt8(count) ]
}
// The number of bytes needed to encode count.
let lengthBytesCount = Int((log2(Double(count)) / 8) + 1)
// The first byte in the length field encoding the number of remaining bytes.
let firstLengthFieldByte = UInt8(128 + lengthBytesCount)
var lengthField: [UInt8] = []
for _ in 0..<lengthBytesCount {
// Take the last 8 bits of count.
let lengthByte = UInt8(count & 0xff)
// Add them to the length field.
lengthField.insert(lengthByte, at: 0)
// Delete the last 8 bits of count.
count = count >> 8
}
// Include the first byte.
lengthField.insert(firstLengthFieldByte, at: 0)
return lengthField
}
现在我们终于拥有了我们想要的数据。
let keyData = Data(bytes: sequenceEncoded)
您可以使用此数据创建SecKey
。
// RSA key size is the number of bits of the modulus.
let keySize = (modulus.count * 8)
let attributes: [String: Any] = [
kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
kSecAttrKeyClass as String: kSecAttrKeyClassPublic,
kSecAttrKeySizeInBits as String: keySize
]
let publicKey = SecKeyCreateWithData(keyData as CFData, attributes as CFDictionary, nil)
我希望这有帮助!如果您需要更多信息,请与我们联系。
答案 1 :(得分:0)
这是我创建RSA密钥对的方法,以防万一有人需要它。
//tuple type for public/private key pair at class level
typealias KeyPair = (publicKey: SecKey, privateKey: SecKey)
func generate() {
// In your code block
let publicKeyTag: String = "com.example.inc.public"
let privateKeyTag: String = "com.example,inc.private"
let keyPair = generateKeyPair(publicKeyTag, privateTag: privateKeyTag, keySize: 1024)
var pbError:Unmanaged<CFError>?
var prError:Unmanaged<CFError>?
if #available(OSX 10.12, *) {
guard let pbData = SecKeyCopyExternalRepresentation((keyPair?.publicKey)!, &pbError) as Data? else {
print("error: ", pbError!.takeRetainedValue() as Error)
return
}
guard let prData = SecKeyCopyExternalRepresentation((keyPair?.privateKey)!, &prError) as Data? else {
print("private key error: ")
return
}
print("Public: \(pbData.bytes)")
print("Private: \(prData.bytes)")
let strPublicKey = appendPrefixSuffixTo(pbData.base64EncodedString(options: .lineLength64Characters), prefix: "-----BEGIN RSA PUBLIC KEY-----\n", suffix: "\n-----END RSA PUBLIC KEY-----")
print("public key: \n", strPublicKey)
let strPrivateKey = appendPrefixSuffixTo(prData.base64EncodedString(options: .lineLength64Characters), prefix: "-----BEGIN RSA PRIVATE KEY-----\n", suffix: "\n-----END RSA PRIVATE KEY-----")
print("private key: \n", strPrivateKey)
} else {
// Fallback on earlier versions
}
}
func generateKeyPair(_ publicTag: String, privateTag: String, keySize: Int) -> KeyPair? {
var publicKey, privateKey: SecKey?
let publicKeyAttr: [NSObject: NSObject] = [
kSecAttrIsPermanent:true as NSObject,
kSecAttrApplicationTag:publicTag.data(using: String.Encoding.utf8)! as NSObject,
kSecClass: kSecClassKey, // added this value
kSecReturnData: kCFBooleanFalse] // added this value
let privateKeyAttr: [NSObject: NSObject] = [
kSecAttrIsPermanent:true as NSObject,
kSecAttrApplicationTag:privateTag.data(using: String.Encoding.utf8)! as NSObject,
kSecClass: kSecClassKey, // added this value
kSecReturnData: kCFBooleanFalse] // added this value
var keyPairAttr = [NSObject: Any]()
keyPairAttr[kSecAttrType] = kSecAttrKeyTypeRSA
keyPairAttr[kSecAttrKeySizeInBits] = 1024
keyPairAttr[kSecReturnData] = true
keyPairAttr[kSecPublicKeyAttrs] = publicKeyAttr as NSObject
keyPairAttr[kSecPrivateKeyAttrs] = privateKeyAttr as NSObject
if SecKeyGeneratePair(keyPairAttr as CFDictionary, &publicKey, &privateKey) == 0 {
print("RSA key pair generation Successful")
return KeyPair(publicKey: publicKey!, privateKey: privateKey!)
}
return nil
}
func appendPrefixSuffixTo(_ string: String, prefix: String, suffix: String) -> String {
return "\(prefix)\(string)\(suffix)"
}