From: Aredeji D. <ar...@ho...> - 2006-08-09 17:01:21
|
I was unable to decode PGP files encrypted with multiple keys. Only one of the private keys would work during the decryption. The following code seems to be a part of the problem. public class PGPDecodedMessageInputStream public void engineInit(InputStream in, DecryptionKeyCallback dkc, VerificationKeyCallback vkc) line 191: while (it.hasNext()) { PGPPublicKey pubsubkey = (PGPPublicKey)it.next(); PGPPrivateKey privsubkey; try { privsubkey = (PGPPrivateKey) pgpbundle.getPrivateSubKey( pubsubkey, val.getPassphrase()); PGPEncryptor cryptor = (PGPEncryptor) privsubkey.getPacket().getAlgorithm(); for (int i=0; i<sessionkeys.size(); i++) { if (sessionkeys.elementAt(i) instanceof PGPPublicKeyEncryptedSessionKeyPacket) { PGPPublicKeyEncryptedSessionKeyPacket pkeskp = (PGPPublicKeyEncryptedSessionKeyPacket) sessionkeys.elementAt(i); boolean success = false; pkeskp.decrypt(cryptor); success = true; if (success) { decryptkey = pkeskp.getSessionKey(); } } } } catch (UnrecoverableKeyException uke) { } catch (PGPDataFormatException e) { } catch (PGPDecryptionFailedException e) { } I have changed the above code to: while (it.hasNext()) { PGPPublicKey pubsubkey = (PGPPublicKey)it.next(); PGPPrivateKey privsubkey; try { privsubkey = (PGPPrivateKey) pgpbundle.getPrivateSubKey( pubsubkey, val.getPassphrase()); PGPEncryptor cryptor = (PGPEncryptor) privsubkey.getPacket().getAlgorithm(); KeyIDFactory kidf = KeyIDFactory.getInstance(PGPConstants.OPENPGP); KeyID kID_Decrypt = kidf.generateKeyID((PublicKey)pubsubkey); for (int i=0; i<sessionkeys.size(); i++) { if (sessionkeys.elementAt(i) instanceof PGPPublicKeyEncryptedSessionKeyPacket) { PGPPublicKeyEncryptedSessionKeyPacket pkeskp = (PGPPublicKeyEncryptedSessionKeyPacket) sessionkeys.elementAt(i); boolean success = false; if((PGPHex.toString(pkeskp.getKeyID())).equals(PGPHex.toString(kID_Decrypt.getBytes(8)))) { pkeskp.decrypt(cryptor); success = true; } if (success) { decryptkey = pkeskp.getSessionKey(); } } } } catch (UnrecoverableKeyException uke) { } catch (PGPDataFormatException e) { } catch (PGPDecryptionFailedException e) { } catch (NoSuchAlgorithmException e) { } catch (InvalidKeyException e) { } } It seems to be working now. I can decode files encrypted with multiple keys. I was also unable to decode PGP files of certain size. I changed the following code public int read(byte[] b, int off, int len) throws IOException { try { if (buf.length - bufoffset >= len) { System.arraycopy(buf, bufoffset, b, 0, len); if (mdc != null) mdc.update(b, 0, len); bufoffset += len; return len; } byte[] temp; if (in.available() > 32) { temp = new byte[(int)in.available() & 0xffffffe0]; if (temp.length < len+blocksize*2+2) temp = new byte[len+blocksize*2+2]; } else { temp = new byte[len+blocksize*2+2]; } if ((in.available() == 0) && (buf.length - bufoffset == 0)) return 0; int size = in.readBuffer(temp); byte[] data; if (size < temp.length) { try { data = cipher.doFinal(temp, 0, size); } catch (IllegalBlockSizeException ibse) { throw new IOException(""+ibse); } catch (BadPaddingException bpe) { throw new IOException(""+bpe); } } else { data = cipher.update(temp, 0, size); } size = 0; if (bufoffset < buf.length) { System.arraycopy(buf, bufoffset, b, off, buf.length-bufoffset); size += buf.length-bufoffset; } if (size + data.length > len) { System.arraycopy(data, 0, b, off+size, len-size); int newbuflen = data.length-(len-size); buf = new byte[newbuflen]; System.arraycopy(data, len-size, buf, 0, newbuflen); bufoffset = 0; if (mdc != null) mdc.update(b, 0, len); return len; } else { System.arraycopy(data, 0, b, off+size, data.length); bufoffset = buf.length; if (mdc != null) mdc.update(b, 0, size + data.length); return size + data.length; } } catch (PGPDataFormatException pdfe) { throw new IOException(""+pdfe); } catch (PGPFatalDataFormatException pdfe) { throw new IOException(""+pdfe); } } to public int read(byte[] b, int off, int len) throws IOException { try { if (buf.length - bufoffset >= len) { System.arraycopy(buf, bufoffset, b, 0, len); if (mdc != null) mdc.update(b, 0, len); bufoffset += len; return len; } byte[] temp; if (in.available() > 32) { temp = new byte[(int)in.available() & 0xffffffe0]; if (temp.length < len+blocksize*2+2) temp = new byte[len+blocksize*2+2]; } else { temp = new byte[len+blocksize*2+2]; //FIXME if(temp.length == in.available()) { temp = new byte [temp.length * 2]; } } if ((in.available() == 0) && (buf.length - bufoffset == 0)) { return 0; } int size = in.readBuffer(temp); byte[] data; if (size < temp.length) { try { data = cipher.doFinal(temp, 0, size); } catch (IllegalBlockSizeException ibse) { throw new IOException(""+ibse); } catch (BadPaddingException bpe) { throw new IOException(""+bpe); } } else { data = cipher.update(temp, 0, size); } size = 0; if (bufoffset < buf.length) { System.arraycopy(buf, bufoffset, b, off, buf.length-bufoffset); size += buf.length-bufoffset; } if (size + data.length > len) { System.arraycopy(data, 0, b, off+size, len-size); int newbuflen = data.length-(len-size); buf = new byte[newbuflen]; System.arraycopy(data, len-size, buf, 0, newbuflen); bufoffset = 0; if (mdc != null) mdc.update(b, 0, len); return len; } else { System.arraycopy(data, 0, b, off+size, data.length); bufoffset = buf.length; if (mdc != null) mdc.update(b, 0, size + data.length); return size + data.length; } } catch (PGPDataFormatException pdfe) { throw new IOException(""+pdfe); } catch (PGPFatalDataFormatException pdfe) { throw new IOException(""+pdfe); } } Please let me know what permanent changes can be made to ensure successful decoding. Best wishes, Ared _________________________________________________________________ On the road to retirement? Check out MSN Life Events for advice on how to get there! http://lifeevents.msn.com/category.aspx?cid=Retirement |