Posts

Post not yet marked as solved
2 Replies
1.1k Views
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: 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: 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 - 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 - 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: UnmanagedCFError?     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   }
Posted
by srini_rao.
Last updated
.
Post marked as solved
6 Replies
2.5k Views
I'm trying to generate a JWK from an EC public key that I want to send to my server. The issue I'm running into is that the base64 URL Encoded string representation of the x and y coordinates from the external representation of the EC public key seems to be invalid on the server and I get an error saying that the points are not on the curve. Here's what I'm doing to generate the base64 URL encoded string from the x and y coords: (NSArray<NSString *> *)getBase64EncodedCoordinatesFromECPublicKey:(SecKeyRef)publicKey error:(out NSError **)error{   CFErrorRef copyPublicKeyError = NULL;   NSData* keyData = (NSData*)CFBridgingRelease(     SecKeyCopyExternalRepresentation(publicKey, &copyPublicKeyError)   );   if (!keyData) {     NSError *err = CFBridgingRelease(copyPublicKeyError);     NSLog(@"%@", err);     return nil;   }   NSString *xbytes;   NSString *ybytes;       CFByteOrder byteOrder = CFByteOrderGetCurrent();   NSLog(@"%ld",(long)byteOrder);       NSData *xData = [keyData subdataWithRange:NSMakeRange(1, 32)];   NSData *xDataRev = [self reverseData:xData];   NSString *xEncoded = [OIDTokenUtilities encodeBase64urlNoPadding:xDataRev];       NSData *yData = [keyData subdataWithRange:NSMakeRange(33, 32)];   NSData *yDataRev = [self reverseData:yData];   NSString *yEncoded = [OIDTokenUtilities encodeBase64urlNoPadding:yDataRev];       xbytes = [OIDTokenUtilities encodeBase64urlNoPadding:xData];   ybytes = [OIDTokenUtilities encodeBase64urlNoPadding:yData];   NSArray *coordinates = @[xbytes, ybytes];   return coordinates; } The byte order on iOS seems to be little-endian (byteOrder above is 1 == CFByteOrderLittleEndian) and the JWK RFC 7517 Appendix A says it expects the big-endian values for x and y. So, I tried swapping the bytes to create a big-endian representation of the data. But, neither works. I'd appreciate any insight or help with this.
Posted
by srini_rao.
Last updated
.