开发者

PGP decryption on iOS

I'm trying to implement decryption of a PGP file on an iPad. I set up some test .txt files which I then encrypted via PGP desktop.

I've imported the private key of the certificate used to encrypt the document, using SecPKCS12Import, then SecIdentityCopyPrivateKey() from the resulting SecIdentityRef.

If I test encrypting and decrypting a simple string in Objective C, using the public and private key of the cert, that works perfectly.

Now that I'm trialling the actual PGP decryption, I'm a bit stumped... Reading the text from the .pgp file, I get:

-----BEGIN PGP MESSAGE-----
Version: 10.1.1.10

qANQR1DBwEwDraQm2Kxa5GkBB/4yLebeLk10C2DVvHpQL20E0DThhgQlTasXo+YJ
pLp5Ig2hHu4Xx0m74D3vfyWpA2XQA02TMAHO9lhNfkE234c/ds05D1UyQkJEoqW+
joEcbRT5rlGN3qrMf1FXv8/01EHH0dgeD6mAkkDeDEorIirYHCF6+QVkedaphZLs
c63GmcikzkWZT/vv20ICL3Ys0DaC3P9zu0T1GtjkmQ062kaTab/VBJnQrsY/y1JU
ypmbW9bbFeZMcAqXHMqpjw49K5UluIJaDbRNAjIvHTFLNuOYWVJM6FcMs5p6xqvZ
ltizeKAjr1B1h4DvbQaqdO6/OAb+dGr7fJoIHEszDsJbW1cc0lUBitrxKHrPGovF
1uEW+3glA3SopveWB4GkKzcYlbqT5y1p/gQNwY8yuZr/6iF1hyF9mx/hU/+xjOMB
og3sGX4npcQegsAMw2y+zz9kJ9a6jlteNufi
=d2Fq
-----END PGP MESSAGE-----

I know that I need to get the random one-time key, that PGP used to encrypt the file, from the data in the file. I know that to do that, I need to use SecKeyDecrypt with the private key, to obtain the one-time AES key. Once I have that key, I can then decrypt the rest of the data.

The part I'm having problems with is which part of the data to feed into SecKeyDecrypt. How is the PGP file setup - is the first 128 chars the AES key? Unless my understanding is wrong, I need to get that out separately from the data.

If I run, say, the first 128 chars as a void through the SecKeyDecrypt function: (after stripping the BEGIN PGP MESSAGE lines)

size_t dataLength = [theKey length]; 
size_t outputLength = MAX(128, SecKeyGetBlockSize(privateKeyRef));
void *outputBuf = malloc(outputLength);  

OSStatus err;

err = SecKeyDecrypt(privateKeyRef, kSecPaddingNone,//PKCS1, 
                                  (uint8_t *)theKey, dataLength,
                                 outputBuf, &outputLength);
if (err) {
    NSLog(@"something went wrong...err = %ld", err);
}

I get this:

MRªh6∞bJ˘e£t*˝ã=ŒA¢Òt‘ŸY±éÿAÃîâG Îfi≠$b≈tâç`yxk=uHªqu-,–dïn^™È\›5±tb.‡€Kñ⁄≤sΩw–ïʃkafS˘À*Æô竡rAyv)fi]wOrµKz^ªq“à∑öΓı*r<+l˝Äo∑›g≠¶/÷eÔ&€PÒRåêM¶Ñ|Q$á6În^võ¬∏·h(ƒß•R≤(flò(*•Aa

I don't know what encoding this is, but trying to get it from the outputBuf into a string never works 100%. It seems to get modified no matter what encoding I pass it. If I pass it to NSData first, I can get the original string back.

NSData *keyData = [NSData dataWithBytesNoCopy:outputBuf length:outputLength];
NSString *keyFromData = [[NSString alloc] initWithBytes:[keyData bytes] length:[keyData length] encoding:NSASCIIStringEncoding]; 

I then try to pass that key to an AES256DecryptWithKey class, providing it with the remaining data from the PGP file, after the first 128 chars.

NSData *cipherText = [[NSData alloc]initWithData:[[bodyPart objectAtIndex:1]   dataUsingEncoding:NSUTF8StringEncoding]];

NSData *plain = [[NSData alloc] initWithData:[cipherText AES256DecryptWithKey:keyFromData]];
NSLog(@"after decrypting = %@", [[NSString alloc] initWithData:plain encoding:NSUTF8StringEncoding]);

Problem:

The resulting data 'plain' prints as <> i.e. empty. My problem is I don't even think I know how to grab the key from the PGP file.

Can anyone explain to me the PGP file setup? What part is the 'key' if it is in fact separate from the data at all? Is it always the same length/ same position? If it's NOT separate then I don't know how I'd be able to grab it at all. I think the rest would work fine. I'm not getting any errors or crashes, it's just NOT the right key and/or data I'm passing for AES decryption开发者_JAVA百科, I suspect probably a combination of string encoding error and not grabbing the right amount for the AES key/ right combination.

Note -

I created 3 different text files and ran them through the PGP process. Inspecting them, they all started with the same 24 characters (qANQR1DBwEwDraQm2Kxa5GkB). Even if I pass these 24 through the decryption, it doesn't work, and I was under the impression that the AES key PGP used was different for every single document. Did I get that wrong?

Thanks for any step in the right direction!

Edited to add:

Just noticed partly my mistake - AES of 128 requires 16 bits, so either way I am taking the wrong amount by using 128 characters, stupid mistake, think I've been looking at this too long... Swapped it out and didn't work. Any decryption I do is resulting in the '⁄Ĉ¢ï¡0M¶È2Cˆ¿©gUú¨6iîΩ`&<%Jœv£¯nRb∆:(–%' type result, which to me implies I've done something wrong OR need to do something further with encoding.


Read RFC 4880. That file is an ASCII-Armored collection of PGP packets. There are 1 or more packets that contain the symmetric key needed to decrypt the actual message, each of the symmetric key packets is encrypted with the public key of a recipient. Only people who possess the right private key can decrypt the symmetric key packet and then use that symmetric key to decrypt the rest of the message.


The AES key is indeed different. It is randomly selected, and the encrypted with the public key system (RSA, typically). Pub key has costs and limitations that make it unattractive to use for bulk.

You might want to look at the NetPGP, which is C code under the BSD license, which means you can incorporate it or modify it without encumbering your app or upsetting Apple in any way. (Of course, contributions of source code or money would be appreciated by the project. I'm not affiliated with them.)

The OpenPGP standard is a lot of work to implement. Even once an implementation works, there are countless ways in which it can be insecure.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜