I'm using an EC public key generated on iOS to encrypt some text on our server. The encryption works fine and I'm using the base64 encoded cipher text on the device to decrypt it using the private key. However, the decryption fails with this error:
The code to encrypt on the server is:
The following method takes the base64 encoded string returned by the server and calls the decryption method using the private key -
Here's the decrypt method -
Code Block language "algid:encrypt:ECIES:ECDHC:KDFX963:SHA256:AESGCM-KDFIV: algorithm not supported by the key <SecKeyRef curve type: kSecECCurveSecp256r1, algorithm id: 3, key type: ECPrivateKey, version: 4, block size: 256 bits, addr: 0x7f9d1f108270>" UserInfo={numberOfErrorsDeep=1, NSDescription=algid:encrypt:ECIES:ECDHC:KDFX963:SHA256:AESGCM-KDFIV: algorithm not supported by the key <SecKeyRef curve type: kSecECCurveSecp256r1, algorithm id: 3, key type: ECPrivateKey, version: 4, block size: 256 bits, addr: 0x7f9d1f108270>, NSUnderlyingError=0x60000072dec0 {Error Domain=NSOSStatusErrorDomain Code=-50 "ECpriv sharedsecret: bad public key (err -7)" UserInfo={numberOfErrorsDeep=0, NSDescription=ECpriv sharedsecret: bad public key (err -7)}}}
The code to encrypt on the server is:
Code Block java private static String encrypt(String plaintext, PublicKey publicKey, String curveName) throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { byte[] inputBytes = plaintext.getBytes(); org.bouncycastle.jce.spec.IESParameterSpec params = new IESParameterSpec(null, null, 128, 128, null); IESCipherGCM cipher = new IESCipherGCM( new IESEngineGCM( new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA256Digest()), new AESGCMBlockCipher()), 16); cipher.engineInit(Cipher.ENCRYPT_MODE, publicKey, params, new SecureRandom()); byte[] cipherResult = cipher.engineDoFinal(inputBytes, 0, inputBytes.length); return Base64.getUrlEncoder().encodeToString(cipherResult); }
The following method takes the base64 encoded string returned by the server and calls the decryption method using the private key -
Code Block Swift func handleDecrypt() -> Void { let data = textField.text?.data(using: .utf8) let clearText = encryptionManager.decryptData(cipherTextData: data, key: aliceKey) print(clearText!) }
Here's the decrypt method -
Code Block Swift public func decryptData(cipherTextData: Data!, key: SecKey!) -> String? { let algorithm: SecKeyAlgorithm = .eciesEncryptionCofactorVariableIVX963SHA256AESGCM guard SecKeyIsAlgorithmSupported(key!, .decrypt, algorithm) else { print("algorithm not supported") return nil } var error: Unmanaged<CFError>? let clearTextData = SecKeyCreateDecryptedData(key!, algorithm, cipherTextData! as CFData, &error) as Data? guard clearTextData != nil else { print("decryption failed") return nil } let clearText = String(decoding: clearTextData!, as: UTF8.self) return clearText }