用于Java后端加密解密的iOS椭圆曲线密钥

2024-06-16 09:28:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我是一名iOS开发人员,试图使用Secure enclave生成ECC对密钥。我可以在这里使用示例应用程序成功地做到这一点:https://github.com/agens-no/EllipticCurveKeyPair。当我将此密钥与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密钥。 然后将公钥传递给Java代码以创建加密消息。此加密消息将传回上述iOS应用程序示例,并使用ECIE加密标准X963SHA256AESGCM算法进行解密。 但是我们得到了下面提到的一个错误。 enter image description here


Tags: no代码httpsgithubcom应用程序消息示例
2条回答

在Java中有两个有趣的类-ECGenParameterSpecKeyPairGeneratorECGenParameterSpec指定用于生成椭圆曲线域参数的参数,KeyPairGenerator用于生成公钥和私钥对

在Nokilay Elenkov的书Android Security Internals中,有一个很好的代码示例,说明了它们的组合可以生成密钥对

KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDH");
ECGenParameterSpec ecParamSpec = new ECGenParameterSpec("secp256r1");
kpg.initialize(ecParamSpec);
KeyPair keyPair = kpg.generateKeyPair();

这是对前面代码的解释

There are two ways to initialize a KeyPairGenerator: by specifying the desired key size and by specifying algorithm-specific parameters. In both cases, you can optionally pass a SecureRandom instance to be used for key generation. If only a key size is specified, key generation will use default parameters (if any). To specify additional parameters, you must instantiate and configure an AlgorithmParameterSpec instance appropriate for the asymmetric algorithm you are using and pass it to the initialize() method, as shown in Example 5-15. In this example, the ECGenParameterSpec initialized in line 2 is an AlgorithmParameterSpec that allows you to specify the curve name used when generating Elliptic Curve (EC) cryptography keys. After it is passed to the initialize() method in line 3, the subsequent generateKeyPair() call in line 4 will use the specified curve (secp256r1) to generate the key pair.

我们也有同样的问题。我们希望在iOS安全enclave上使用Java后端实现EC密钥交换

经过三天的审讯,;错误,我们终于找到了一个正在工作的Java实现

Java代码取自https://github.com/O2-Czech-Republic/BC-ECIES-for-iOS

和iOS代码,使用ECiseEncryptionCofactorVariableIVX963SHA256AESGCM算法:

  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
            }
        }
    }

相关问题 更多 >