Swift SecKeyRawSign返回错误-1,“1”;一般性错误;?

Swift SecKeyRawSign返回错误-1,“1”;一般性错误;?,swift,security,public-key-encryption,sha256,Swift,Security,Public Key Encryption,Sha256,我正在开发一个iOS应用程序,该应用程序需要在设备上生成密钥对,将私钥存储在安全Enclave中,然后稍后访问它以用于签名(永远不需要导出)。当我签名时,我总是使用SHA256对数据进行散列,然后是几个堆栈溢出答案,当我打印结果时,它似乎工作正常。但是,在从密钥链获取有效的私钥引用、对要签名的数据进行散列并指定它是SHA256散列之后,SecKeyRawSign仍然返回-1。这只是列为“一般错误”,我的设置似乎应该是有效的。如果您能深入了解问题所在,我们将不胜感激。以下是我生成和签名的方法: p

我正在开发一个iOS应用程序,该应用程序需要在设备上生成密钥对,将私钥存储在安全Enclave中,然后稍后访问它以用于签名(永远不需要导出)。当我签名时,我总是使用SHA256对数据进行散列,然后是几个堆栈溢出答案,当我打印结果时,它似乎工作正常。但是,在从密钥链获取有效的私钥引用、对要签名的数据进行散列并指定它是SHA256散列之后,SecKeyRawSign仍然返回-1。这只是列为“一般错误”,我的设置似乎应该是有效的。如果您能深入了解问题所在,我们将不胜感激。以下是我生成和签名的方法:

private func genKeyPair() -> (privateAlias: String, publicKey: NSData)? {

    // Generate a keyhandle, which will be returned as an alias for the private key
    let numBytes = Int(keyHandleLength)
    var randomBytes = [UInt8](count: numBytes, repeatedValue: 0)
    SecRandomCopyBytes(kSecRandomDefault, numBytes, &randomBytes)
    let data = NSData(bytes: &randomBytes, length: numBytes)
    let alias = data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))

    let access = SecAccessControlCreateWithFlags(nil, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, .TouchIDCurrentSet, nil)!

    // Key pair parameters
    var keyParams: [String:AnyObject] = [
        kSecAttrKeyType as String: kSecAttrKeyTypeEC,
        kSecAttrKeySizeInBits as String: 256
    ]

    // Private key parameters
    keyParams[kSecPrivateKeyAttrs as String] = [
        kSecAttrIsPermanent as String: true,
        kSecAttrLabel as String: alias,
        kSecAttrApplicationTag as String: applicationTag,
        kSecAttrAccessControl as String: access
    ]

    // Public key parameters
    keyParams[kSecPublicKeyAttrs as String] = [
        kSecAttrIsPermanent as String: true,
        kSecAttrLabel as String: alias + "-pub",
        kSecAttrApplicationTag as String: applicationTag
    ]

    var pubKeyRef, privKeyRef: SecKey?
    var err = SecKeyGeneratePair(keyParams, &pubKeyRef, &privKeyRef)

    guard let _ = pubKeyRef where err == errSecSuccess else {

        print("Error while generating key pair: \(err).")
        return nil

    }

    // Export the public key for application use
    let query = [
        kSecClass as String: kSecClassKey,
        kSecAttrLabel as String: alias + "-pub",
        kSecAttrKeyType as String: kSecAttrKeyTypeEC,
        kSecReturnData as String: true
    ]
    var pubKeyOpt: AnyObject?
    err = SecItemCopyMatching(query, &pubKeyOpt)

    if let pubKey = pubKeyOpt as? NSData where err == errSecSuccess {

        print("Successfully retrieved public key!")
        return (alias, pubKey)

    } else {

        print("Error retrieving public key: \(err).")
        return nil

    }

}

private func sign(bytes data: NSData, usingKeyWithAlias alias: String) -> NSData? {

    let query = [
        kSecClass as String: kSecClassKey,
        kSecAttrLabel as String: alias,
        kSecAttrApplicationTag as String: applicationTag,
        kSecAttrKeyType as String: kSecAttrKeyTypeEC,
        kSecReturnRef as String: true
    ]

    var privateKey: AnyObject?
    var error = SecItemCopyMatching(query, &privateKey)

    guard error == errSecSuccess else {

        print("Could not obtain reference to private key with alias \"\(alias)\", error: \(error).")
        return nil

    }

    print("\nData: \(data)")
    print("Length: \(data.length)")

    let hashedData = NSMutableData(length: Int(CC_SHA256_DIGEST_LENGTH))!
    CC_SHA256(data.bytes, CC_LONG(data.length), UnsafeMutablePointer(hashedData.mutableBytes))

    print("\nHashed data: \(hashedData)")
    print("Length: \(hashedData.length)")

    var signedHashLength = SecKeyGetBlockSize(privateKey as! SecKeyRef)
    let signedHash = NSMutableData(length: signedHashLength)!

    error = SecKeyRawSign(privateKey as! SecKeyRef, .PKCS1SHA256, UnsafePointer<UInt8>(hashedData.mutableBytes), hashedData.length, UnsafeMutablePointer<UInt8>(signedHash.mutableBytes), &signedHashLength)

    print("\nSigned hash: \(signedHash)")
    print("Length: \(signedHashLength)\n")

    guard error == errSecSuccess else {

        print("Failed to sign data, error: \(error).")
        return nil

    }

    return signedHash

}
private func genKeyPair()->(privateAlias:String,publicKey:NSData)?{
//生成一个keyhandle,它将作为私钥的别名返回
设numBytes=Int(keyHandleLength)
var randomBytes=[UInt8](计数:numBytes,repeatedValue:0)
SecRandomCopyBytes(kSecRandomDefault、numBytes和randomBytes)
let data=NSData(字节:&randomBytes,长度:numBytes)
让alias=data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue:0))
让access=SecAccessControlCreateWithFlags(nil,ksecattraccessiblewwhenpasscodestetthissdeviceonly,.TouchIDCurrentSet,nil)!
//密钥对参数
var keyParams:[字符串:AnyObject]=[
kSecAttrKeyType作为字符串:KSECATTRKEYTYPEC,
kSecAttrKeySizeInBits作为字符串:256
]
//私钥参数
keyParams[kSecPrivateKeyAttrs作为字符串]=[
kSecAttrIsPermanent作为字符串:true,
kSecAttrLabel作为字符串:别名,
kSecAttrApplicationTag作为字符串:applicationTag,
kSecAttrAccessControl作为字符串:访问
]
//公钥参数
keyParams[kSecPublicKeyAttrs作为字符串]=[
kSecAttrIsPermanent作为字符串:true,
kSecAttrLabel作为字符串:别名+“-pub”,
kSecAttrApplicationTag作为字符串:applicationTag
]
var pubKeyRef,privKeyRef:SecKey?
var err=SecKeyGeneratePair(keyParams、&pubKeyRef、&privKeyRef)
guard let=pubKeyRef,其中err==errSecSuccess-else{
打印(“生成密钥对时出错:\(错误)。”)
归零
}
//导出公钥以供应用程序使用
让查询=[
kSecClass作为字符串:kSecClassKey,
kSecAttrLabel作为字符串:别名+“-pub”,
kSecAttrKeyType作为字符串:KSECATTRKEYTYPEC,
kSecReturnData作为字符串:true
]
var pubKeyOpt:AnyObject?
err=SecItemCopyMatching(查询和pubKeyOpt)
如果让pubKey=pubKeyOpt作为NSData,其中err==errSecSuccess{
打印(“已成功检索公钥!”)
return(别名,pubKey)
}否则{
打印(“检索公钥时出错:\(错误)。”)
归零
}
}
专用func符号(字节数据:NSData,usingKeyWithAlias别名:String)->NSData?{
让查询=[
kSecClass作为字符串:kSecClassKey,
kSecAttrLabel作为字符串:别名,
kSecAttrApplicationTag作为字符串:applicationTag,
kSecAttrKeyType作为字符串:KSECATTRKEYTYPEC,
kSecReturnRef作为字符串:true
]
var privateKey:任何对象?
var error=SecItemCopyMatching(查询和私钥)
保护错误==errSecSuccess-else{
打印(“无法获取对别名为\(别名)\”的私钥的引用,错误:\(错误)。”
归零
}
打印(“\n数据:\(数据)”)
打印(“长度:\(data.Length)”)
让hashedData=NSMutableData(长度:Int(CC_SHA256_DIGEST_length))!
CC_SHA256(data.bytes,CC_LONG(data.length),unsafemtablepointer(hashedData.mutableBytes))
打印(“\n隐藏数据:\(哈希数据)”)
打印(“长度:\(hashedData.Length)”)
var signedHashLength=SecKeyGetBlockSize(privateKey为!SecKeyRef)
让signedHash=NSMutableData(长度:signedHashLength)!
error=SecKeyRawSign(privateKey为!SecKeyRef、.PKCS1SHA256、UnsafePointer(hashedData.mutableBytes)、hashedData.length、UnsafeMutablePointer(signedHash.mutableBytes)和signedHashLength)
打印(“\n签名哈希:\(签名哈希)”)
打印(“长度:\(signedHashLength)\n”)
保护错误==errSecSuccess-else{
打印(“签署数据失败,错误:\(错误)。”)
归零
}
返回签名哈希
}