/src/csc479_hw4_gui/PKE.java

https://bitbucket.org/kurtsiegfried/csc479_hw4_gui · Java · 216 lines · 169 code · 29 blank · 18 comment · 6 complexity · 7f636552cc5bce3684d317ab91cd6d0b MD5 · raw file

  1. /*
  2. * To change this template, choose Tools | Templates
  3. * and open the template in the editor.
  4. */
  5. package csc479_hw4_gui;
  6. import java.io.BufferedReader;
  7. import java.io.DataInputStream;
  8. import java.io.File;
  9. import java.io.FileInputStream;
  10. import java.io.FileOutputStream;
  11. import java.io.FileReader;
  12. import java.io.IOException;
  13. import java.io.PrintWriter;
  14. import java.security.KeyFactory;
  15. import java.security.KeyPair;
  16. import java.security.KeyPairGenerator;
  17. import java.security.PrivateKey;
  18. import java.security.PublicKey;
  19. import java.security.spec.PKCS8EncodedKeySpec;
  20. import java.security.spec.X509EncodedKeySpec;
  21. import java.util.Formatter;
  22. import javax.crypto.Cipher;
  23. import javax.crypto.CipherInputStream;
  24. import javax.crypto.CipherOutputStream;
  25. import javax.crypto.KeyGenerator;
  26. import javax.crypto.SecretKey;
  27. import javax.crypto.spec.SecretKeySpec;
  28. /**
  29. *
  30. * @author ksiegfried
  31. */
  32. public class PKE {
  33. static final String symmetricAlgorithm = "Blowfish";
  34. static final String asymmetricAlgorithm = "RSA";
  35. static final String pkInstance = "RSA/ECB/PKCS1Padding";
  36. static final int RSASIZE = 2048;
  37. static final int BFSIZE = 128;
  38. static final int CIPHERTEXTSIZE = 256;
  39. static final boolean append = true;
  40. public static final int GENERATION_SUCCESS = 0;
  41. public static final int GENERATION_FAILURE = 1;
  42. public static PrivateKey recoverPrivateKey(String fileName) throws Exception {
  43. try {
  44. BufferedReader bReader = new BufferedReader(new FileReader(fileName));
  45. byte[] privKeyBytes = hexStringToByteArray(bReader.readLine());
  46. PrivateKey privKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privKeyBytes));
  47. bReader.close();
  48. return privKey;
  49. } catch (Exception e) {
  50. e.printStackTrace();
  51. throw e;
  52. }
  53. }
  54. public static PublicKey recoverPublicKey(String fileName) throws Exception {
  55. try {
  56. BufferedReader bReader = new BufferedReader(new FileReader(fileName));
  57. byte[] pubKeyBytes = hexStringToByteArray(bReader.readLine());
  58. PublicKey pubKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(pubKeyBytes));
  59. bReader.close();
  60. return pubKey;
  61. } catch (Exception e) {
  62. e.printStackTrace();
  63. throw e;
  64. }
  65. }
  66. private static void writeKey(String key, File f) throws IOException {
  67. PrintWriter pr = new PrintWriter(new FileOutputStream(f));
  68. pr.println(key);
  69. pr.flush();
  70. pr.close();
  71. }
  72. public static int generateKeyPair(String pathName) {
  73. File pubFile, privFile;
  74. PrivateKey privKey;
  75. PublicKey pubKey;
  76. try {
  77. KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
  78. kpg.initialize(2048);
  79. KeyPair keypair = kpg.generateKeyPair();
  80. pubKey = keypair.getPublic();
  81. System.out.println("Public Key Bytes: " + pubKey.getEncoded().length);
  82. privKey = keypair.getPrivate();
  83. System.out.println("Private Key Bytes: " + privKey.getEncoded().length);
  84. pubFile = new File(pathName, "MyRSAKeys.public");
  85. privFile = new File(pathName, "MyRSAKeys.private");
  86. writeKey(byteArray2Hex(pubKey.getEncoded()), pubFile);
  87. writeKey(byteArray2Hex(privKey.getEncoded()), privFile);
  88. } catch (Exception e) {
  89. System.out.println(e);
  90. return PKE.GENERATION_FAILURE;
  91. }
  92. return PKE.GENERATION_SUCCESS;
  93. }
  94. public static boolean encrypt(PublicKey pubKey, String fileName) {
  95. try {
  96. /*Set outfile*/
  97. File outFile = new File(fileName + ".encrypted");
  98. /*Initialize symmetric key crytpo*/
  99. SecretKey symmetricKey;
  100. KeyGenerator bkg = KeyGenerator.getInstance(symmetricAlgorithm);
  101. bkg.init(BFSIZE);
  102. symmetricKey = bkg.generateKey();
  103. byte[] secretBytes = symmetricKey.getEncoded();
  104. System.out.println("Secret Bytes Length: " + secretBytes.length);
  105. System.out.println("Secret Key Bytes: " + byteArray2Hex(secretBytes));
  106. Cipher BlowfishCipher = Cipher.getInstance(symmetricAlgorithm);
  107. BlowfishCipher.init(Cipher.ENCRYPT_MODE, symmetricKey);
  108. /*Set up RSA Cipher*/
  109. Cipher c = Cipher.getInstance(pkInstance);
  110. c.init(Cipher.ENCRYPT_MODE, pubKey);
  111. byte[] cipherText = c.doFinal(secretBytes);
  112. /*Save Encrypted Key*/
  113. FileOutputStream fOS = new FileOutputStream(outFile);
  114. fOS.write(cipherText);
  115. fOS.flush();
  116. fOS.close();
  117. /*Append encrypted data to key*/
  118. fOS = new FileOutputStream(outFile, append);
  119. FileInputStream fIS = new FileInputStream(fileName);
  120. CipherOutputStream cOS = new CipherOutputStream(fOS, BlowfishCipher);
  121. DataInputStream dIS = new DataInputStream(fIS);
  122. int count;
  123. while ((count = dIS.read()) != -1) {
  124. cOS.write(count);
  125. cOS.flush();
  126. }
  127. cOS.close();
  128. fOS.close();
  129. dIS.close();
  130. } catch (Exception e) {
  131. e.printStackTrace();
  132. return false;
  133. }
  134. return true;
  135. }
  136. public static boolean decrypt(PrivateKey privKey, String fileName, String outFileName) {
  137. try {
  138. /*Set up public key cipher*/
  139. byte[] recoveredBytes = new byte[256];
  140. Cipher c = Cipher.getInstance(pkInstance);
  141. c.init(Cipher.DECRYPT_MODE, privKey);
  142. /*Recover symmetric key*/
  143. FileInputStream fIS = new FileInputStream(new File(fileName));
  144. System.out.println("Read bytes: " + fIS.read(recoveredBytes));
  145. System.out.println("Recovered Text: " + byteArray2Hex(recoveredBytes));
  146. recoveredBytes = c.doFinal(recoveredBytes);
  147. System.out.println("Recovered Bytes: " + byteArray2Hex(recoveredBytes));
  148. /*Initialize symmetric cipher for decryption*/
  149. SecretKeySpec BFKeySpec = new SecretKeySpec(recoveredBytes, "Blowfish");
  150. Cipher symmetricCipher = Cipher.getInstance("Blowfish");
  151. symmetricCipher.init(Cipher.DECRYPT_MODE, BFKeySpec);
  152. /*Skip past secret key block*/
  153. fIS = new FileInputStream(new File(fileName));
  154. fIS.skip(256);
  155. /*Read, and decrypt file. Store plaintext in output file*/
  156. CipherInputStream cIS = new CipherInputStream(fIS, symmetricCipher);
  157. FileOutputStream fOS = new FileOutputStream(new File(outFileName));
  158. int read;
  159. while ((read = cIS.read()) != -1) {
  160. fOS.write(read);
  161. fOS.flush();
  162. }
  163. fOS.close();
  164. cIS.close();
  165. } catch (Exception e) {
  166. e.printStackTrace();
  167. return false;
  168. }
  169. return true;
  170. }
  171. private static String byteArray2Hex(byte[] hash) {
  172. Formatter formatter = new Formatter();
  173. for (byte b : hash) {
  174. formatter.format("%02x", b);
  175. }
  176. return formatter.toString();
  177. }
  178. private static byte[] hexStringToByteArray(String s) {
  179. int len = s.length();
  180. byte[] data = new byte[len / 2];
  181. for (int i = 0; i < len; i += 2) {
  182. data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
  183. + Character.digit(s.charAt(i + 1), 16));
  184. }
  185. return data;
  186. }
  187. }