Java tutorial
/************************************************************************ * Copyright (c) Crater Dog Technologies(TM). All Rights Reserved. * ************************************************************************ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * * * This code is free software; you can redistribute it and/or modify it * * under the terms of The MIT License (MIT), as published by the Open * * Source Initiative. (See http://opensource.org/licenses/MIT) * ************************************************************************/ package craterdog.security; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.security.KeyPair; import java.security.PrivateKey; import java.security.PublicKey; import javax.crypto.SecretKey; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.ext.XLogger; import org.slf4j.ext.XLoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * This class provides unit tests for all methods in the MessageCryptex class. * * @author Derk Norton */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:META-INF/spring/craterdog-secure-messaging-providers.xml" }) public class RsaAesMessageCryptexTest { static XLogger logger = XLoggerFactory.getXLogger(RsaAesMessageCryptexTest.class); /** * Log a message at the beginning of the tests. */ @BeforeClass public static void setUpClass() { logger.info("Running RsaAesMessageCrytex Unit Tests...\n"); } /** * Log a message at the end of the tests. */ @AfterClass public static void tearDownClass() { logger.info("RsaAesMessageCrytex Unit Tests Completed.\n"); } @Autowired private MessageCryptex cryptex; /** * This test encrypts a test string and then decrypts it and compares the two to make sure * that they are the same. */ @Test public void testStringRoundTrip() { logger.info("Testing round trip string encryption..."); logger.info(" Generating a shared key..."); SecretKey sharedKey = cryptex.generateSharedKey(); logger.info(" Encrypting a test string with the shared key..."); String string = "This is a test string."; byte[] encryptedString = cryptex.encryptString(sharedKey, string); logger.info(" Decrypting the encrypted string with the shared key..."); String decryptedString = cryptex.decryptString(sharedKey, encryptedString); logger.info(" Comparing the two strings..."); assertEquals("The decrypted string was different from the original string", string, decryptedString); logger.info("Round trip string encryption test completed.\n"); } /** * This test method performs a round-trip session key generation, encryption, signing, * encoding, decoding, signature verification, and decryption tests using the MessageCryptex * class. * * @throws IOException */ @Test public void testMessageRoundTrip() throws IOException { logger.info("Testing round trip message encryption..."); logger.info(" Generating the public/private key pairs..."); RsaCertificateManager manager = new RsaCertificateManager(); KeyPair senderPair = manager.generateKeyPair(); PrivateKey senderPrivateKey = senderPair.getPrivate(); PublicKey senderPublicKey = senderPair.getPublic(); KeyPair receiverPair = manager.generateKeyPair(); PrivateKey receiverPrivateKey = receiverPair.getPrivate(); PublicKey receiverPublicKey = receiverPair.getPublic(); logger.info(" Sender generating shared session key..."); SecretKey sessionKey = cryptex.generateSharedKey(); logger.info(" Sender encrypting session key..."); byte[] encryptedSessionKey = cryptex.encryptSharedKey(receiverPublicKey, sessionKey); logger.info(" Sender signing the encrypted session key..."); byte[] signature = cryptex.signBytes(senderPrivateKey, encryptedSessionKey); logger.info(" Sender base 64 encoding the encrypted key and signature..."); String encodedSessionKey = cryptex.encodeBytes(encryptedSessionKey); logger.info(" EncodedSessionKey: " + encodedSessionKey); String encodedSignature = cryptex.encodeBytes(signature); logger.info(" EncodedSignature: " + encodedSignature); logger.info(" Sender encrypting the request using session key..."); String request = "This is a request..."; InputStream clearInput = new ByteArrayInputStream(request.getBytes("UTF-8")); ByteArrayOutputStream encryptedOutput = new ByteArrayOutputStream(); cryptex.encryptStream(sessionKey, clearInput, encryptedOutput); logger.info(" Sender sending the encrypted request to the receiver..."); InputStream encryptedInput = new ByteArrayInputStream(encryptedOutput.toByteArray()); logger.info(" Receiver decoding the encrypted session key and its signature..."); signature = cryptex.decodeString(encodedSignature); encryptedSessionKey = cryptex.decodeString(encodedSessionKey); logger.info(" Receiver validating the signature of the encrypted session key..."); if (!cryptex.bytesAreValid(senderPublicKey, encryptedSessionKey, signature)) { fail("The session key signature was invalid."); } logger.info(" Receiver decrypting the session key..."); sessionKey = cryptex.decryptSharedKey(receiverPrivateKey, encryptedSessionKey); logger.info(" Receiver decrypting the request using the session key..."); ByteArrayOutputStream decryptedOutput = new ByteArrayOutputStream(); cryptex.decryptStream(sessionKey, encryptedInput, decryptedOutput); assertEquals("The decrypted request was different from the original request", request, new String(decryptedOutput.toByteArray())); logger.info(" Receiver handling the request and preparing the response..."); String response = "This is the response..."; logger.info(" Receiver encrypting the response using the session key..."); clearInput = new ByteArrayInputStream(response.getBytes("UTF-8")); encryptedOutput = new ByteArrayOutputStream(); cryptex.encryptStream(sessionKey, clearInput, encryptedOutput); logger.info(" Receiver sending the encrypted response to the sender..."); encryptedInput = new ByteArrayInputStream(encryptedOutput.toByteArray()); logger.info(" Sender decrypting the response using the session key..."); decryptedOutput = new ByteArrayOutputStream(); cryptex.decryptStream(sessionKey, encryptedInput, decryptedOutput); assertEquals("The decrypted response was different from the original response", response, new String(decryptedOutput.toByteArray())); logger.info("Round trip message encryption test completed.\n"); } }