Archived Forum Post

Index of archived forum posts

Question:

Issues decrypting data encrypted with OpenSSL using ChilKat RSA pub key

Sep 01 '14 at 08:56

Hi there.

I’m having an issue with consistently decrypting data with the ChilKat iOS library that is encrypted with my device’s RSA public key by a PHP environment, using OpenSSL. The issue is that the encrypted data will decrypt correctly at times, but will not with error output from ChilKat in others.

Here’s how my workflow looks.

1) I generate 2048-bit RSA keys with the ChilKat library. The private key is stored kept in memory in XML format, while the public key is sent along to my environment in PEM format.

- (void)generateRSAKeyPair
{
    BOOL success;
        CkoRsa *rsa = [[CkoRsa alloc] init];

        success = [rsa UnlockComponent: CHILKAT_UNLOCK_KEY];
        if (!success) {    
            return;
        }

    success = [rsa GenerateKey: @2048];
        if (!success) {
            return;
        }

    if (success) {
            CkoPublicKey *devicePubKey = [rsa ExportPublicKeyObj];
            NSString *tempPath = [NSTemporaryDirectory() stringByAppendingString: @"devicePubKey.der"];
            success = [devicePubKey SaveOpenSslPemFile: tempPath];
            if (!success) {
                return;
            }
            NSError *err = nil;
            NSString *tempPemFile = [NSString stringWithContentsOfFile: tempPath
                                                              encoding: NSASCIIStringEncoding
                                                                 error: &err];
            if (err) {
                return;
            } else {
                self.rsaPublicKey = tempPemFile;
                [[NSFileManager defaultManager] removeItemAtPath: tempPath error: nil];
            }

            self.rsaPrivateKey = [rsa ExportPrivateKey];
        }
}

2) Later, several pieces of data are encrypted with my device public key and then Base-64 encoded by my PHP environment, as a JSON blob. When I receive them, I serialize the blob and try to decrypt the encrypted fields using this method:

- (NSString *) decryptDataWithRSAPrivateKey: (NSData *) encryptedData {

    BOOL success = NO;

    if (!self.rsaPrivateKey) {
        self.rsaPrivateKey = [[FXKeychain defaultKeychain] objectForKey: kLifeLockDeviceRSAPrivKey];
    }

    if (!self.rsaPrivateKey) {
        return nil;
    }

    self.rsaDevicePrivateKey = [CkoPrivateKey new];
    success = [self.rsaDevicePrivateKey LoadXml: self.rsaPrivateKey];

    if (!success) {
        NSLog(@"%@", self.rsaDevicePrivateKey.LastErrorText);
        return nil;
    }

    // Create a new RSA object to decrypt our data.
    self.rsaInterface = [CkoRsa new];

    success = [self.rsaInterface UnlockComponent: CHILKAT_UNLOCK_KEY];

    if (!success) {
        NSLog(@"%@", self.rsaInterface.LastErrorText);
        return nil;
    }

    success = [self.rsaInterface ImportPrivateKeyObj: self.rsaDevicePrivateKey];

    if (!success) {
        NSLog(@"%@", self.rsaInterface.LastErrorText);
        return nil;
    }

    NSData *decryptedData = [self.rsaInterface DecryptBytes: encryptedData bUsePrivateKey: YES];

    if (!decryptedData) {
        NSLog(@"%@", self.rsaInterface.LastErrorText);
        return nil;
    }

    NSString *result = [[NSString alloc] initWithData: decryptedData encoding: NSUTF8StringEncoding];

    return result;

}

The above method will work…sometimes. Other times, however, the method errors out when I try to actually decrypt the data, with the following error out of ChilKat:

exptmod_decoded_size: 256
        padding: PKCS 1.5
        Pkcs1_5_decode:
          Invalid PKCS v1.5 PS length
          ps_len: 254
        --Pkcs1_5_decode
        Packet: 2EAB3D9D03581F56E92F836B03242CC3FD5E8A6A7AEE4BA42544F65161AB532BC0F8F375AE300A44C8EBAA358326047D37771113B6AA0BC5A65C7C126AFBB7E7472199FF89B687D245346FA1ABEF9F90DC3D23B6710CB87B3D1982BB2CFA314DCA84D9AB689F6AD930EE84A2E56C45F85E4E7F212FF10391B0361570A5ECF53B77BABEC9C32B8401B8AAFEFFE5FA6FB178EC4995F4EC29B8BF4C8987AAE9217B38361D5CF2511B977BD838519F796F25287685AEAA6C856F0E7EA48767457B36F5A21D752ADD327D27D3BCB65106A602FDB0B5CD83DAB20EBAD95EABE7B822CD058807A4F7CC72D33C1C6C89EFA8F70D1003F8FF07DCEBB95C78C2673290AD75
      --RSA_decrypt
    --rsaDecryptBytes
    Failed.
  --DecryptBytes
--ChilkatLog

Is there something I’m missing here?

Thanks in advance.

EDIT: I've made sure to match the LittleEndian settings on the server, so that's not the issue.


Answer

This problem is "resolved" in that Edgar is no longer able to reproduce the problem. It is unknown as to what was the original cause, but whatever it may have been, it seems to have been fixed.

This was an older email response to the problem:

I think this is the error one would get if the incorrect private key is used to decrypt. In other words, the data is encrypted using a public key, but the attempt is to decrypt with a private key that is not the counterpart to the public key used for encryption.

Decryption with the correct private key would result in PKCS v1.5 padded data. This is then unpadded to arrive at the original non-encrypted data. If the wrong private key was used, then the decryption would produce garbage bytes -- which would (of course) not conform to the PKCS v1.5 format. The error would be seen when trying to PKCS v1.5 unpad, which is what we see here.

... If you have RSA encrypted data that OpenSSL can successfully decrypt, but Chilkat cannot, then I would need the private key and the encrypted data. I would verify that OpenSSL is able to decrypt using the key, and then would verify that Chilkat fails. If this is the case, then it proves in an error within Chilkat. However, if both OpenSSL and Chilkat fail to decrypt, then the error is in the data and/or key.