我是加密新手。我想seckey
从数据中创建公共,但我总是得到零。请帮我。我需要这个公钥seckey
来创建一个shared secrete key
,但我总是得到 nil 。我如何将数据转换为seckey
?
以下是参考代码。我正在使用快速语言。
let attributes: [String:Any] = [
kSecAttrKeyClass as String: kSecAttrKeyClassPublic,
kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
kSecAttrKeySizeInBits as String: 512,
]
var pubKey = publicKey2
var error1: Unmanaged<CFError>?
/// Create seckey
guard let pubSecKey = SecKeyCreateWithData((Data(bytes: publicKey2) as CFData), attributes as CFDictionary, &error1)else{
print(error1?.takeRetainedValue().localizedDescription)
return []
}
var error: Unmanaged<CFError>?
/// create shared key
guard let shared1 = SecKeyCopyKeyExchangeResult(LSILock.privtKey, .ecdhKeyExchangeCofactorX963SHA256, pubSecKey, keyPair, &error) else {
return []
}
print(shared1)
更新
以下是我要转换为 seckey 的字节:
[12, 178, 30, 213, 113, 166, 59, 63, 203, 236, 182, 205, 126, 28, 81, 13, 94, 98, 67, 231, 152, 244, 180, 213, 168, 190, 237, 88, 131, 159, 173, 131, 75, 203, 51, 193, 115, 60, 36, 158, 27, 27, 174, 4, 211, 63, 25, 13, 174, 174, 64, 35, 59, 58, 151, 193, 167, 225, 13, 142, 237, 255, 25, 38]
if characteristic.uuid.uuidString == LSILock.AUTHENTICATION_KEY_EXHANGE {
print(value)
let hexValue = value.toHexString()
print(hexValue)
if let d = hexValue.lowercased().dataFromHexadecimalString() {
print(d.bytes)
LSILock.goForPrivatekeys = LSILock.goForPrivatekeys + 1
let dropFirst = d.bytes.dropFirst(1)
let dropLast = dropFirst.dropLast(3)
LSILock.lockPublicKey.append(contentsOf: dropLast)
if LSILock.goForPrivatekeys == 4{
LSILock.goForPrivatekeys = 0
let secKey = aesCTRencrytion(publicKey2: LSILock.lockPublicKey, keyPair: LSILock.keyPairs as CFDictionary)
print(secKey)
privateKeyExchange(secKey)
}
}
}
func dataFromHexadecimalString() -> Data? {
let trimmedString = self.trimmingCharacters(in: CharacterSet(charactersIn: "<> ")).replacingOccurrences(of: " ", with: "")
// make sure the cleaned up string consists solely of hex digits, and that we have even number of them
let regex: NSRegularExpression?
do {
regex = try NSRegularExpression(pattern: "^[0-9a-f]*$", options: .caseInsensitive)
} catch _ as NSError {
regex = nil
}
let found = regex?.firstMatch(in: trimmedString, options: [], range: NSMakeRange(0, trimmedString.count))
if found == nil || found?.range.location == NSNotFound || trimmedString.count % 2 != 0 {
return nil
}
// everything ok, so now let's build NSData
let data = NSMutableData(capacity: trimmedString.count / 2)
for i in stride(from:0,to:trimmedString.count,by:2) {
let start = trimmedString.index(trimmedString.startIndex, offsetBy: i)
let end = trimmedString.index(trimmedString.startIndex, offsetBy: i+1)
// get a sub-string with a ClosedRange
let range = start...end
let byteString = trimmedString[range]
let num=UInt8(byteString.withCString { strtoul($0, nil, 16) })
data?.append([num] as [UInt8], length: 1)
}
return data as Data?
}
func aesCTRencrytion( publicKey2 : [UInt8], keyPair : CFDictionary ) -> [UInt8]{
let message = "001C971A3456"
let messageData = message.dataFromHexadecimalString()!.bytes
print(ivData)
let attributes: [String:Any] = [
kSecAttrKeyClass as String: kSecAttrKeyClassPublic,
kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
kSecAttrKeySizeInBits as String: 512,
kSecReturnPersistentRef as String : true
]
var pubKey = publicKey2
var error1: Unmanaged<CFError>?
/// Create seckey
guard let pubSecKey = SecKeyCreateWithData((Data(bytes: publicKey2) as CFData), attributes as CFDictionary, &error1)else{
print(error1?.takeRetainedValue().localizedDescription)
return []
}
var error: Unmanaged<CFError>?
/// create shared key
guard let shared1 = SecKeyCopyKeyExchangeResult(LSILock.privtKey, .ecdhKeyExchangeCofactorX963SHA256, pubSecKey, keyPair, &error) else {
return []
}
print(shared1)
}
下面我生成一对密钥:
func ecdhEncryption() {
// let privComponents = try? CC.EC.getPrivateKeyComponents(LSILock.keys!.0)
// let pubComponents = try? CC.EC.getPublicKeyComponents(LSILock.keys!.1)
//
// let pubKey = try? CC.EC.createFromData( pubComponents!.keySize, pubComponents!.x, pubComponents!.y)
// print(pubKey)
// let pubKey1 = try? CC.EC.getPublicKeyFromPrivateKey(LSILock.keys!.0)
// print(pubKey1)
// guard let lock = LockSmartAPI.sharedInstance.getLock(lock_sn) else{return}
// lock.keyExchange(pubKey!)
var publicKey = [UInt8]()
var privateKey = [UInt8]()
var publicKeySec, privateKeySec: SecKey?
let keyattribute = [
SecKeyKeyExchangeParameter.requestedSize.rawValue as String: 32,
kSecAttrKeyType as String: kSecAttrKeyTypeEC,
kSecAttrKeySizeInBits as String : 256
] as CFDictionary
SecKeyGeneratePair(keyattribute, &publicKeySec, &privateKeySec)
LSILock.keyPairs = keyattribute as! [String : Any]
var error:Unmanaged<CFError>?
if let publicCfdata = SecKeyCopyExternalRepresentation(publicKeySec!, &error) {
let data:Data = publicCfdata as Data
print(data)
let b64Key = data.base64EncodedString()
print(b64Key)
}
if let privateCfdata = SecKeyCopyExternalRepresentation(privateKeySec!, &error) {
let data:Data = privateCfdata as Data
print(data)
let b64Key = data.base64EncodedString()
print(b64Key)
}
// guard let privateKey1 = SecKeyCreateRandomKey(keyattribute as CFDictionary, &error) else {
// return
// }
// let publicKey1 = SecKeyCopyPublicKey(privateKey1)
// print(publicKey1 as? Data ?? Data())
// print(publicKeySec)
// print(privateKeySec)
var error1: Unmanaged<CFError>?
let keyData = SecKeyCopyExternalRepresentation(privateKeySec!, &error1)
let data = keyData! as Data
var privateKeyBytes = data.bytes
privateKeyBytes.removeFirst()
//For public key bytes will be divide into 2
let pointSize = privateKeyBytes.count / 3
let xBytes = privateKeyBytes[0..<pointSize]
publicKey.append(contentsOf: xBytes)
let yBytes = privateKeyBytes[pointSize..<pointSize*2]
publicKey.append(contentsOf: yBytes)
print(publicKey)
//dBytes wont be there in public key
let dBytes = privateKeyBytes[pointSize*2..<pointSize*3]
privateKey.append(contentsOf: dBytes)
// this x, y and d bytes can be expressed in HexaDecimal format or base64 format
print(dBytes)
// LSILock.privatekeys = Array(privateKey[0..<min(16,privateKey.count)])
LSILock.privtKey = privateKeySec
guard let lock = LockSmartAPI.sharedInstance.getLock(lock_sn) else{return}
lock.keyExchange(publicKey)
}