我是一名 iOS 开发人员,正在尝试使用 Secure enclave 生成 ECC 对 key 。我可以使用此处的示例应用程序成功做到这一点:https://github.com/agens-no/EllipticCurveKeyPair 。当我使用此 key 与 Python 实现一起进行此处提到的加密和解密时:https://gist.github.com/dschuetz/2ff54d738041fc888613f925a7708a06有用。
问题是我需要 Java 代码来执行相同的操作。任何人都可以帮助我实现这一目标,或者向我指出一个与 Python 代码所做的工作相同的代码。
在 iOS 端,我正在执行 eciesEncryptionStandardX963SHA256AESGCM
加密和解密逻辑。
我知道我应该尝试自己解决这个问题。但我是一名 iOS 工程师,正在尝试 Java 后端。如果有人可以指导我,那将会非常有帮助。
根据答案创建了示例 Java 代码。链接代码:https://gist.github.com/balrajOla/fa2f6030538b20a396c086377a6f7114
使用此处提供的示例 iOS 应用程序:https://github.com/agens-no/EllipticCurveKeyPair 。我生成了 ECC key 。 然后将公钥传递给 Java 代码以创建加密消息。此加密消息会传回上述示例 iOS 应用程序,并使用 eciesEncryptionStandardX963SHA256AESGCM 算法进行解密。 但我们得到了下面提到的错误快照。
最佳答案
我们也遇到了同样的问题。我们希望通过 Java 后端在 iOS 安全区域实现 EC key 交换。
经过三天的反复试验,我们终于找到了一个可以运行的 Java 实现。
Java 代码取自 https://github.com/O2-Czech-Republic/BC-ECIES-for-iOS
iOS代码,使用eciesEncryptionCofactorVariableIVX963SHA256AESGCM算法:
static func getExportableKeyFromECKey() -> String? {
// If exists already a created EC Key, then export the public part
if let privateKey = self.loadECPrivateKey() {
if let publicKey = self.getECPublicKey(privateKey) {
if self.algorithmAcceptedForEC(publicKey) {
var error: Unmanaged<CFError>?
// Get Public key External represenatation
guard let cfdata = SecKeyCopyExternalRepresentation(publicKey, &error) else {
return nil
}
let pubKeyData: Data = cfdata as Data
return pubKeyData.base64EncodedString()
}
}
}
// If no EC Key created, then first create one
else {
var error: Unmanaged<CFError>?
let tag = Config.skName.data(using: .utf8) ?? Data()
let attributes: [String: Any] = [kSecClass as String: kSecClassKey,
kSecAttrKeyType as String: Config.skType,
kSecAttrKeySizeInBits as String: Config.ecKeySize,
kSecPrivateKeyAttrs as String: [ kSecAttrIsPermanent as String: true,
kSecAttrApplicationTag as String: tag]]
do {
// Create Private Key
guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
throw error!.takeRetainedValue() as Error
}
// Get Public Key
guard let publicKey = SecKeyCopyPublicKey(privateKey) else {
throw error!.takeRetainedValue() as Error
}
// Get Public key External represenatation
guard let cfdata = SecKeyCopyExternalRepresentation(publicKey, &error) else {
throw error!.takeRetainedValue() as Error
}
let pubKeyData: Data = cfdata as Data
return pubKeyData.base64EncodedString()
} catch {
print(error)
}
}
return nil
}
static func loadECPrivateKey() -> SecKey? {
let tag = Config.skName.data(using: .utf8)!
let query: [String: Any] = [kSecClass as String: kSecClassKey,
kSecAttrApplicationTag as String: tag,
kSecAttrKeyType as String: Config.skType,
kSecReturnRef as String: true]
var item: CFTypeRef?
let status = SecItemCopyMatching(query as CFDictionary, &item)
guard status == errSecSuccess else {
return nil
}
print("LOAD PRIVATE KEY: \n \(item as! SecKey) \n")
return (item as! SecKey)
}
static func getECPublicKey(_ privateKey: SecKey) -> SecKey? {
guard let publicKey = SecKeyCopyPublicKey(privateKey) else {
// Can't get public key
return nil
}
return publicKey
}
static func algorithmAcceptedForEC(_ publicKey: SecKey) -> Bool {
guard SecKeyIsAlgorithmSupported(publicKey, .encrypt, Config.ecAlgorithm) else {
// Algorith not supported
print("\nEncrytion Algorithm not supported!!!\n")
return false
}
return true
}
/// if let encryptedData = Data(base64Encoded: "BOqw779hxsGLMEV7X81Mphcx+SMtxSQs388s5CydkvJ4V2XuuWoyp48GCmgDMBnYlEIRqAdHxIc/Ts3ATxa9ENCDGdIZf5CjpWsOIVXYxLvupdap4w==", options:.ignoreUnknownCharacters)
static func decryptStr(_ encData: Data) {
/// 1. Step: Get the Private Key and decrypt the symmetric key
let privateKey = loadECPrivateKey()
guard SecKeyIsAlgorithmSupported(privateKey!, .decrypt, Config.ecAlgorithm) else {
print("Can't decrypt\nAlgorithm not supported")
return
}
DispatchQueue.global().async {
var error: Unmanaged<CFError>?
let clearTextData = SecKeyCreateDecryptedData(privateKey!,
Config.ecAlgorithm,
encData as CFData,
&error) as Data?
DispatchQueue.main.async {
guard clearTextData != nil else {
print("Can't decrypt")
return
}
let clearText = String(decoding: clearTextData!, as: UTF8.self)
print("Decrypted Info: \(clearText)")
// clearText is our decrypted string
}
}
}
关于java - iOS椭圆曲线 key 用于Java后端加密解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60437690/