/Frameworks/Core/ERExtensions/Sources/er/extensions/crypting/ERXKeyStoreBlowfishCrypter.java

https://bitbucket.org/molequedeideias/wonder · Java · 164 lines · 99 code · 21 blank · 44 comment · 11 complexity · 9ea167ae2659b771eb2b748349787dbf MD5 · raw file

  1. package er.extensions.crypting;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileNotFoundException;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import java.security.Key;
  8. import java.security.KeyStore;
  9. import java.security.KeyStoreException;
  10. import java.security.NoSuchAlgorithmException;
  11. import java.security.UnrecoverableKeyException;
  12. import java.security.cert.CertificateException;
  13. import javax.crypto.spec.SecretKeySpec;
  14. import er.extensions.foundation.ERXProperties;
  15. /**
  16. * <p>
  17. * ERXKeyStoreBlowfishCrypter is a blowfish implementation of the crypter
  18. * interface that loads its secret key from a java keystore.
  19. * </p>
  20. * <p>
  21. * Because the java keystore API is so damn ridiculous, you can use the main
  22. * method provided in this class to generate the keystore with your blowfish
  23. * password in it.
  24. * </p>
  25. * <p>
  26. * If you want to just use all of the default values, you can run this class's
  27. * main method from inside eclipse with the arguments:
  28. * </p>
  29. *
  30. * <code>
  31. * "" "" "" "" "yourblowfishpassword"
  32. * </code>
  33. *
  34. * <p>
  35. * The easiest way to choose to use this crypter is to override the default
  36. * blowfish crypter with the Properties entries:
  37. * </p>
  38. *
  39. * <code>
  40. * er.extensions.ERXCrypto.crypters=Blowfish
  41. * er.extensions.ERXCrypto.crypter.Blowfish=er.extensions.ERXKeyStoreBlowfishCrypter
  42. * </code>
  43. *
  44. * @author mschrag
  45. * @property er.extensions.ERXKeyStoreBlowfishCrypter.keystorePath the path of
  46. * the keystore that contains the blowfish key for this crypter. The
  47. * default keystore path is
  48. * "~/.er.extensions.ERXKeyStoreBlowfishCrypter.keystore"
  49. * @property er.extensions.ERXKeyStoreBlowfishCrypter.keystorePassword the
  50. * keystore password (if necessary)
  51. * @property er.extensions.ERXKeyStoreBlowfishCrypter.keyAlias the alias of the
  52. * blowfish key in the keystore
  53. * @property er.extensions.ERXKeyStoreBlowfishCrypter.keyPassword the password
  54. * of the blowfish key in the keystore (if necessary)
  55. */
  56. public class ERXKeyStoreBlowfishCrypter extends ERXAbstractBlowfishCrypter {
  57. private static final String KEYSTORE_TYPE = "JCEKS";
  58. private static final String DEFAULT_KEY_ALIAS = "er.extensions.ERXBlowfishCipherKey";
  59. private static final String DEFAULT_KEY_PASSWORD = "er.extensions.ERXBlowfishCipherKey";
  60. private static final String DEFAULT_KEYSTORE_PASSWORD = "er.extensions.ERXBlowfishCipherKey";
  61. private static final String defaultKeyStorePath() {
  62. return new File(System.getProperty("user.home"), ".er.extensions.ERXKeyStoreBlowfishCrypter.keystore").getAbsolutePath();
  63. }
  64. @Override
  65. protected Key secretBlowfishKey() throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, CertificateException, IOException {
  66. String keystorePath = ERXProperties.stringForKeyWithDefault("er.extensions.ERXKeyStoreBlowfishCrypter.keystorePath", ERXKeyStoreBlowfishCrypter.defaultKeyStorePath());
  67. File keystoreFile = new File(keystorePath);
  68. KeyStore keyStore = KeyStore.getInstance(ERXKeyStoreBlowfishCrypter.KEYSTORE_TYPE);
  69. if (!keystoreFile.exists()) {
  70. throw new FileNotFoundException("There is no keystore '" + keystoreFile.getAbsolutePath() + "'. Run ERXKeyStoreBlowfishCrypter's main method for help. Oh, and to hell with whoever wrote Java's KeyStore API.");
  71. }
  72. String keystorePasswordStr = ERXProperties.stringForKeyWithDefault("er.extensions.ERXKeyStoreBlowfishCrypter.keystorePassword", ERXKeyStoreBlowfishCrypter.DEFAULT_KEYSTORE_PASSWORD);
  73. char[] keystorePassword = null;
  74. if (keystorePasswordStr != null) {
  75. keystorePassword = keystorePasswordStr.toCharArray();
  76. }
  77. FileInputStream keystoreInputStream = new FileInputStream(keystoreFile);
  78. try {
  79. keyStore.load(keystoreInputStream, keystorePassword);
  80. }
  81. finally {
  82. keystoreInputStream.close();
  83. }
  84. String alias = ERXProperties.stringForKeyWithDefault("er.extensions.ERXKeyStoreBlowfishCrypter.keyAlias", ERXKeyStoreBlowfishCrypter.DEFAULT_KEY_ALIAS);
  85. // We can't use ERXProperties.decryptedStringForKey because it would
  86. // potentially result in an infinite look if this is the default
  87. // crypter.
  88. String keyPasswordStr = ERXProperties.stringForKeyWithDefault("er.extensions.ERXKeyStoreBlowfishCrypter.keyPassword", ERXKeyStoreBlowfishCrypter.DEFAULT_KEY_PASSWORD);
  89. char[] keyPassword = keyPasswordStr.toCharArray();
  90. Key key = keyStore.getKey(alias, keyPassword);
  91. return key;
  92. }
  93. public static void main(String[] args) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException, CertificateException, FileNotFoundException, IOException {
  94. if (args.length != 5) {
  95. System.out.println("ERXKeyStoreBlowfishCrypter.main: [keystorePath] [keystorePassword] [keyAlias] [keyPassword] [blowfishKey]");
  96. System.out.println(" Note: you can set any of the parameters to \"\" to use the default values except for blowfishKey.");
  97. System.exit(0);
  98. }
  99. String keystorePath = ERXKeyStoreBlowfishCrypter.defaultKeyStorePath();
  100. if (args[0].length() > 0) {
  101. keystorePath = args[0];
  102. }
  103. String keystorePasswordStr = ERXKeyStoreBlowfishCrypter.DEFAULT_KEYSTORE_PASSWORD;
  104. if (args[1].length() > 0) {
  105. keystorePasswordStr = args[1];
  106. }
  107. char[] keystorePassword = keystorePasswordStr.toCharArray();
  108. String keyAlias = ERXKeyStoreBlowfishCrypter.DEFAULT_KEY_ALIAS;
  109. if (args[2].length() > 0) {
  110. keyAlias = args[2];
  111. }
  112. String keyPasswordStr = ERXKeyStoreBlowfishCrypter.DEFAULT_KEY_PASSWORD;
  113. if (args[3].length() > 0) {
  114. keyPasswordStr = args[3];
  115. }
  116. char[] keyPassword = keyPasswordStr.toCharArray();
  117. String blowfishKey = args[4];
  118. KeyStore keyStore = KeyStore.getInstance(ERXKeyStoreBlowfishCrypter.KEYSTORE_TYPE);
  119. File keystoreFile = new File(keystorePath);
  120. if (keystoreFile.exists()) {
  121. FileInputStream keystoreInputStream = new FileInputStream(keystoreFile);
  122. try {
  123. keyStore.load(keystoreInputStream, keystorePassword);
  124. }
  125. finally {
  126. keystoreInputStream.close();
  127. }
  128. }
  129. else {
  130. keyStore.load(null, keystorePassword);
  131. }
  132. SecretKeySpec key = new SecretKeySpec(blowfishKey.getBytes(), "Blowfish");
  133. keyStore.setKeyEntry(keyAlias, key, keyPassword, null);
  134. FileOutputStream keystoreOutputStream = new FileOutputStream(keystoreFile);
  135. try {
  136. keyStore.store(keystoreOutputStream, keystorePassword);
  137. }
  138. finally {
  139. keystoreOutputStream.close();
  140. }
  141. System.out.println("ERXKeyStoreBlowfishCrypter.main: Generated the keystore '" + keystorePath + "'.");
  142. }
  143. }