java - iOS椭圆曲线 key 用于Java后端加密解密

标签 java python ios encryption

我是一名 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 算法进行解密。 但我们得到了下面提到的错误快照。 enter image description here

最佳答案

我们也遇到了同样的问题。我们希望通过 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/

相关文章:

python - 温度探头、电压探头等.dll

ios - 如何更改 iOS 系统警报的色调颜色?

java - 在JAVA中将用户的输入存储为字符串

java - HSV 颜色范围检测

java - 使用线程移动图形 2d 对象

java - Apache Commons 配置将属性设置为环境变量 - 如何?

python - 用于图像比较的 SSIM : issue with image shape

python - 如何读取pandas中包含数字字符串数字的自定义表?

ios - 确保核心数据在整个开发周期中持续存在的最佳实践

ios - 将推送通知角标(Badge)添加到 UIButton