/** * Decrypts the encrypted part of the packet with the private key of an <code>EmailIdentity</code>. * The {@link CryptoImplementation} in the <code>EmailIdentity</code> must be the same as the one * in this <code>EncryptedEmailPacket</code>. * @param identity * @throws GeneralSecurityException * @throws InvalidCipherTextException */ public UnencryptedEmailPacket decrypt(EmailIdentity identity) throws GeneralSecurityException { if (cryptoImpl != identity.getCryptoImpl()) throw new IllegalArgumentException("CryptoImplementations don't match. Email Packet: <" + cryptoImpl.getName() + ">, Email Identity: <" + identity.getCryptoImpl().getName() + ">."); byte[] decryptedData = cryptoImpl.decrypt(encryptedData, identity.getPublicEncryptionKey(), identity.getPrivateEncryptionKey()); return new UnencryptedEmailPacket(decryptedData); }
/** * Creates a signature over the byte array representation of the packet * @param identity An email identity that matches the destination field * @param keyUpdateHandler * @throws PasswordException * @throws GeneralSecurityException */ private void sign(EmailIdentity identity, KeyUpdateHandler keyUpdateHandler) throws GeneralSecurityException, PasswordException { byte[] data = getDataToSign(); CryptoImplementation cryptoImpl = identity.getCryptoImpl(); PrivateKey privateSigningKey = identity.getPrivateSigningKey(); signature = cryptoImpl.sign(data, privateSigningKey, keyUpdateHandler); }
byte[] encodedPrivateKey = privateKey.getEncoded().clone(); CryptoImplementation cryptoImpl = identity.getCryptoImpl(); cryptoImpl.sign(message, privateKey, identities);
/** * Creates a digital signature of the email and stores it in the * <code>SIGNATURE_HEADER</code> header field. It also removes the * <code>SIGNATURE_VALID_HEADER</code> header. If there is a signature * already, it is replaced.<br/> * The signature is computed over the stream representation of the * email, minus the signature header if it is present.<br/> * The signature includes the ID number of the {@link CryptoImplementation} * used (signature lengths can be different for the same algorithm). * @param senderIdentity * @param keyUpdateHandler Needed for updating the signature key after signing (see {@link CryptoImplementation#sign(byte[], PrivateKey, KeyUpdateHandler)}) * @throws MessagingException * @throws GeneralSecurityException * @throws PasswordException */ public void sign(EmailIdentity senderIdentity, KeyUpdateHandler keyUpdateHandler) throws MessagingException, GeneralSecurityException, PasswordException { removeHeader(SIGNATURE_HEADER); // make sure there is no existing signature which would make the new signature invalid removeHeader(SIGNATURE_VALID_HEADER); // remove the signature validity flag before signing CryptoImplementation cryptoImpl = senderIdentity.getCryptoImpl(); PrivateKey privateSigningKey = senderIdentity.getPrivateSigningKey(); byte[] signature = cryptoImpl.sign(toByteArray(), privateSigningKey, keyUpdateHandler); String foldedSignature = foldSignature(cryptoImpl.getId() + "_" + Base64.encode(signature)); setHeader(SIGNATURE_HEADER, foldedSignature); }
@Before public void setUp() throws Exception { // make an UnencryptedEmailPacket byte[] content = message.getBytes(); byte[] messageIdBytes = new byte[] {-69, -24, -109, 1, 69, -122, -69, 113, -68, -90, 55, -28, 105, 97, 125, 70, 51, 58, 14, 2, -13, -53, 90, -29, 36, 67, 36, -94, -108, -125, 11, 123}; UniqueId messageId = new UniqueId(messageIdBytes, 0); int fragmentIndex = 0; plaintextPacket = new UnencryptedEmailPacket(new ByteArrayInputStream(content), messageId, fragmentIndex, I2PBotePacket.MAX_DATAGRAM_SIZE); plaintextPacket.setNumFragments(1); encryptedPackets = new EncryptedEmailPacket[2]; identities = new EmailIdentity[2]; // make a ElGamal/DSA identity String elGamalBase64 = "piYT1uJ3O8~bBPZmTvehMbp3-Zksg5enhvIlp2X8txqL25l0WdQMWwyt30UAOVQqxGdnMPTqqjh~-zoa~rCQORo~J1gRxLwCX9LlHQqaIimJilrbN-rhKy4Xlft054wbgQjLSC-WICE4W64KDfitwRzdr7lV6lz~0KFiZ8erZ-~WPMG1CgWEku9lILQUdUHyFBguPcK9oPDq7oGBuFGy8w0CvAq7ex3nmbL7zQVA~VqILtOGeGK2fidCuuofj4AQsTcXmH9O0nxZGCIJBhf~4EWmazvxu8XVB8pabNQvRDbmFu6q85JTwmxC45lCjqNw30hp8q2zoqP-zchjWOrxFUhSumpBdD0xXJR~qmhejh4WnuRnnam9j3fcxH5i~T7xWgmvIbpZEI4kyc9VEbXbLI7k-bU2A6sdP-AGt5~TjGLcxpdsPnOLRXO-Dsi7E9-3Kc84s4TmdpEJdtHn1dxYyeeT-ysVOqXjv5w5Cuk0XJpUIJG8n7aXHpNb-QLxPD3yAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADWF3qnAX-p41Po~VNmOUzS-Yt~noD8-e~L3P5rZXBWf-XtB4hkloo6m1jwqphEdf1"; identities[0] = new EmailIdentity(elGamalBase64); EmailDestination elGamalDestination = new EmailDestination(identities[0].getKey()); // make an ElGamal encrypted packet assertTrue(identities[0].getCryptoImpl() instanceof ElGamal2048_DSA1024); encryptedPackets[0] = new EncryptedEmailPacket(plaintextPacket, elGamalDestination); // make a ECDH/ECDSA identity String ecdhBase64 = "m-5~1dZ0MrGdyAWu-C2ecNAB5LCCsHQpeSfjn-r~mqMfNvroR98~BRmReUDmb0la-r-pBHLMtflrJE7aTrGwDTBm5~AJFEm-9SJPZnyGs-ed5pOj4Db65yJml1y1n77qr1~mM4GITl6KuIoxg8YwvPrCIlXe2hiiDCoC-uY9-np9UYYujtjOOwCqXPH9PIbcZeFRkegbOxw5G6I7M4-TZBFbxYDtaew6HX9hnQEGWHkaapq2kTTB3Hmv0Uyo64jvcfMmSRcPng3J1Ho5mHgnzsH0qxQemnBcw7Lfc9fU8xRz858uyiQ8J8XH3T8S7k2~8L7awSgaT7uHQgpV~Rs0p1ofJ70g"; identities[1] = new EmailIdentity(ecdhBase64); EmailDestination ecdhDestination = new EmailDestination(identities[1].getKey()); // make an ECDH encrypted packet assertTrue(identities[1].getCryptoImpl() instanceof ECDH521_ECDSA521); encryptedPackets[1] = new EncryptedEmailPacket(plaintextPacket, ecdhDestination); }