PageRenderTime 56ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/src/interdroid/util/CryptoUtil.java

https://github.com/interdroid/interdroid-util
Java | 367 lines | 113 code | 38 blank | 216 comment | 0 complexity | fa44a165523816ff0a508b62b6086f33 MD5 | raw file
  1. /*
  2. * Copyright (c) 2008-2012 Vrije Universiteit, The Netherlands All rights
  3. * reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. *
  11. * Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * Neither the name of the Vrije Universiteit nor the names of its contributors
  16. * may be used to endorse or promote products derived from this software without
  17. * specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
  20. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  23. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  27. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29. * POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. package interdroid.util;
  32. import java.io.UnsupportedEncodingException;
  33. import java.security.InvalidKeyException;
  34. import java.security.KeyPair;
  35. import java.security.KeyPairGenerator;
  36. import java.security.MessageDigest;
  37. import java.security.NoSuchAlgorithmException;
  38. import java.security.PrivateKey;
  39. import java.security.PublicKey;
  40. import java.security.Signature;
  41. import java.security.SignatureException;
  42. import javax.crypto.BadPaddingException;
  43. import javax.crypto.Cipher;
  44. import javax.crypto.IllegalBlockSizeException;
  45. import javax.crypto.KeyGenerator;
  46. import javax.crypto.Mac;
  47. import javax.crypto.NoSuchPaddingException;
  48. import javax.crypto.SecretKey;
  49. /**
  50. * A utility library for doing various cryptography related things with sensible defaults.
  51. * Uses java.security and javax.crypto packages and deals only in Strings.
  52. *
  53. * @author nick palmer@cs.vu.nl
  54. *
  55. */
  56. public class CryptoUtil {
  57. /**
  58. * The default encoding for String->byte[] and byte[]->String to use.
  59. */
  60. public static final String DEFAULT_ENCODING = "UTF8";
  61. /**
  62. * The default MAC generation scheme
  63. */
  64. public static final String DEFAULT_MAC = "HmacMD5";
  65. /**
  66. * The default Digest generation scheme
  67. */
  68. public static final String DEFAULT_DIGEST = "MD5";
  69. /**
  70. * The default cypher to use for secret key encryption/decryption
  71. */
  72. public static final String DEFAULT_CYPHER = "Blowfish";
  73. /**
  74. * The default mode to use for secret key encryption/decryption
  75. */
  76. public static final String DEFAULT_MODE = "ECB";
  77. /**
  78. * The default padding scheme to use for secret key encryption/decryption
  79. */
  80. public static final String DEFAULT_PADDING = "PKCS5Padding";
  81. /**
  82. * The default public key encryption scheme
  83. */
  84. public static final String DEFAULT_KEY_PAIR_TYPE = "RSA";
  85. /**
  86. * The default signature scheme
  87. */
  88. public static final String DEFAULT_SIGNATURE_SPEC = "MD5WithRSA";
  89. /**
  90. * The default cypher specification which is the combination of the DEFAULT_CYPHER, DEFAULT_MODE and DEFAULT_PADDING
  91. */
  92. public static final String DEFAULT_CYPHER_SPEC = DEFAULT_CYPHER + "/" + DEFAULT_MODE + "/" + DEFAULT_PADDING;
  93. /**
  94. * The default key size for public key encryption
  95. */
  96. public static final int DEFAULT_KEY_PAIR_SIZE = 2048;
  97. // Signature stuff
  98. /**
  99. * Generates a signature for the given plainTextString using the PrivateKey key and the signature type and
  100. * string encoding scheme specified.
  101. *
  102. * @param plainTextString The text to be signed
  103. * @param key The private key to use to sign
  104. * @param type The signature specification
  105. * @param encoding The string encoding method
  106. * @return The generated signature
  107. * @throws UnsupportedEncodingException if the encoding is not supported
  108. * @throws NoSuchAlgorithmException if the type is not supported
  109. * @throws InvalidKeyException if the private key is invalid
  110. * @throws SignatureException if there is a problem generating the signature
  111. */
  112. public String generateSignatureTypeEncoded(String plainTextString, PrivateKey key, String type, String encoding)
  113. throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
  114. byte[] plainText = plainTextString.getBytes(encoding);
  115. Signature sig = Signature.getInstance(type);
  116. sig.initSign(key);
  117. sig.update(plainText);
  118. byte[] signature = sig.sign();
  119. return new String(signature, encoding);
  120. }
  121. /**
  122. * Generates a signature for the given plain text using the private key and the DEFAULT_SIGNATURE_SPEC and DEFAULT_ENCODING
  123. *
  124. * @param plainTextString The text to sign
  125. * @param key The key to use to generate the signature
  126. * @return The signature
  127. * @throws InvalidKeyException If the key is invalid
  128. * @throws UnsupportedEncodingException If the DEFAULT_ENCODING is not supported
  129. * @throws NoSuchAlgorithmException If the DEFAULT_SIGNATURE_SPEC is not supported
  130. * @throws SignatureException If there is a problem generating the signature
  131. */
  132. public String generateSignature(String plainTextString, PrivateKey key)
  133. throws InvalidKeyException, UnsupportedEncodingException, NoSuchAlgorithmException, SignatureException {
  134. return generateSignatureTypeEncoded(plainTextString, key, DEFAULT_SIGNATURE_SPEC, DEFAULT_ENCODING);
  135. }
  136. /**
  137. * Verifies the signature for the given plain text using the specified key, signature scheme and string encoding
  138. *
  139. * @param plainTextString The plain text to be verified
  140. * @param signatureString The signature to be checked
  141. * @param key The public key to verify with
  142. * @param type The signature scheme being used
  143. * @param encoding The string encoding scheme to use
  144. * @throws NoSuchAlgorithmException If the signature type is not supported
  145. * @throws UnsupportedEncodingException If the encoding type is not supported
  146. * @throws InvalidKeyException If the key is invalid
  147. * @throws SignatureException If there is a problem verifying the signature
  148. */
  149. public void verifySignatureTypeEncoded(String plainTextString, String signatureString, PublicKey key, String type, String encoding)
  150. throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException, SignatureException {
  151. byte[] plainText = plainTextString.getBytes(encoding);
  152. byte[] signature = signatureString.getBytes(encoding);
  153. Signature sig = Signature.getInstance(type);
  154. sig.initVerify(key);
  155. sig.update(plainText);
  156. sig.verify( signature );
  157. }
  158. /**
  159. * Verifies the signature on the given plain text using the specified key using the DEFAULT_SIGNATURE_SPEC and the DEFAULT_ENCODING
  160. *
  161. * @param plainTextString The plain text to be verified
  162. * @param signature The signature to be checked
  163. * @param key The public key to verify with
  164. * @throws NoSuchAlgorithmException If the DEFAULT_SIGNATURE_SPEC is not supported
  165. * @throws UnsupportedEncodingException If the DEFAULT_ENCODING is not supported
  166. * @throws InvalidKeyException If the key is invalid
  167. * @throws SignatureException If there is a problem verifying the signature
  168. */
  169. public void verifySignature(String plainTextString, String signature, PublicKey key)
  170. throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException, SignatureException {
  171. verifySignatureTypeEncoded(plainTextString, signature, key, DEFAULT_SIGNATURE_SPEC, DEFAULT_ENCODING);
  172. }
  173. // Secret Key Encryption and Decryption
  174. /**
  175. * Decrypt using the DEFAULT_CYPHER_SPEC and the DEFAULT_ENCODING
  176. *
  177. * @param plainTextString the plain text to encrypt
  178. * @param key The secret key to do the encoding with
  179. * @throws NoSuchPaddingException If the DEFAULT_PADDING is not supported
  180. * @throws NoSuchAlgorithmException If the DEFAULT_CYPHER not supported
  181. * @throws UnsupportedEncodingException If the DEFAULT_ENCODING is not supported
  182. * @throws InvalidKeyException If the key is invalid
  183. * @throws BadPaddingException If the padding is incorrect for the DEFAULT_PADING
  184. * @throws IllegalBlockSizeException If the block size is incorrect while decrypting
  185. * @return the decrypted text
  186. */
  187. public static String decrypt(String plainTextString, SecretKey key) throws NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
  188. Cipher cipher = Cipher.getInstance(DEFAULT_CYPHER_SPEC);
  189. byte[] plainText = plainTextString.getBytes(DEFAULT_ENCODING);
  190. cipher.init(Cipher.DECRYPT_MODE, key);
  191. return new String(cipher.doFinal(plainText), DEFAULT_ENCODING);
  192. }
  193. /**
  194. * Encrypt using the DEFAULT_CYPHER_SPEC and the DEFAULT_ENCODING
  195. *
  196. * @param plainTextString the plain text to encrypt
  197. * @param key The secret key to do the encoding with
  198. * @throws NoSuchPaddingException If the DEFAULT_PADDING is not supported
  199. * @throws NoSuchAlgorithmException If the DEFAULT_CYPHER is not supported
  200. * @throws UnsupportedEncodingException If the DEFAULT_ENCODING is not supported
  201. * @throws InvalidKeyException If the key is invalid
  202. * @throws BadPaddingException If the padding is incorrect
  203. * @throws IllegalBlockSizeException If there is a block size problem
  204. * @return the encrypted text
  205. */
  206. public static String encrypt(String plainTextString, SecretKey key)
  207. throws NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
  208. Cipher cipher = Cipher.getInstance(DEFAULT_CYPHER);
  209. byte[] plainText = plainTextString.getBytes(DEFAULT_ENCODING);
  210. cipher.init(Cipher.ENCRYPT_MODE, key);
  211. return new String(cipher.doFinal(plainText), DEFAULT_ENCODING);
  212. }
  213. // Key Methods
  214. /**
  215. * Generates a KeyPair with the given type and given size
  216. *
  217. * @param type The type of key pair to generate
  218. * @param size The size of the key pair to generate
  219. * @return The generated key pair
  220. * @throws NoSuchAlgorithmException if the type is not supported
  221. */
  222. public static KeyPair generateKeyPairTypeSize(String type, int size) throws NoSuchAlgorithmException {
  223. KeyPairGenerator keyGen = KeyPairGenerator.getInstance(type);
  224. keyGen.initialize(size);
  225. return keyGen.generateKeyPair();
  226. }
  227. /**
  228. * Generates a KeyPair with the DEFAULT_KEY_PAIR_TYPE and the DEFAULT_KEY_PAIR_SIZE
  229. *
  230. * @return The generated key pair
  231. * @throws NoSuchAlgorithmException If the DEFAULT_KEY_PAIR_TYPE is not supported
  232. */
  233. public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
  234. return generateKeyPairTypeSize(DEFAULT_KEY_PAIR_TYPE, DEFAULT_KEY_PAIR_SIZE);
  235. }
  236. /**
  237. * Generates a new secret key of the requested type
  238. *
  239. * @param type A key type like "HmacMD5" or "DES"
  240. * @param keysize The size of the key to generate
  241. * @return a new SecretKey of the given type and size
  242. * @throws NoSuchAlgorithmException If teh type is not supported
  243. */
  244. public static SecretKey generateSecretKeySized(String type, int keysize)
  245. throws NoSuchAlgorithmException {
  246. KeyGenerator keyGen = KeyGenerator.getInstance(type);
  247. keyGen.init( keysize );
  248. SecretKey key = keyGen.generateKey();
  249. return key;
  250. }
  251. /**
  252. * Generates a new secret key of the requested type
  253. *
  254. * @param type A key type like "HmacMD5"
  255. * @return a new SecretKey of the given type
  256. * @throws NoSuchAlgorithmException If the type is not supported
  257. */
  258. public static SecretKey generateSecretKey(String type)
  259. throws NoSuchAlgorithmException {
  260. KeyGenerator keyGen = KeyGenerator.getInstance(type);
  261. SecretKey key = keyGen.generateKey();
  262. return key;
  263. }
  264. // MAC methods
  265. /**
  266. * Generates a MAC using the specified type and encoding
  267. *
  268. * @param plainTextString The plain text to generate a MAC for
  269. * @param key The key to use to generate the MAC
  270. * @param type The type of algorithm to use
  271. * @param encoding The encoding scheme to use
  272. * @return The MAC for the plain text
  273. * @throws NoSuchAlgorithmException If the type is not supported
  274. * @throws InvalidKeyException If the key is invalid
  275. * @throws UnsupportedEncodingException If the encoding is not supported
  276. */
  277. public static String getMacTypeEncoded(String plainTextString, SecretKey key, String type, String encoding)
  278. throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
  279. Mac mac = Mac.getInstance(type);
  280. mac.init(key);
  281. byte[] plainText = plainTextString.getBytes(encoding);
  282. mac.update(plainText);
  283. return new String(mac.doFinal(), encoding);
  284. }
  285. /**
  286. * Generates a MAC using the DEFAULT_MAC and the DEFAULT_ENCODING
  287. *
  288. * @param plainTextString The plain text to generate a MAC for
  289. * @param key The key to use to generate the MAC
  290. * @return The MAC for the given plain text
  291. * @throws NoSuchAlgorithmException If the DEFAULT_MAC is not supported
  292. * @throws InvalidKeyException If the key is invalid
  293. * @throws UnsupportedEncodingException If the DEFAULT_ENCODING is not supported
  294. */
  295. public static String getMac(String plainTextString, SecretKey key)
  296. throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
  297. return getMacTypeEncoded(plainTextString, key, DEFAULT_MAC, DEFAULT_ENCODING);
  298. }
  299. // Digest Methods
  300. /**
  301. * Generates a digest using the specified digest and encoding
  302. *
  303. * @param plainTextString
  304. * @param type
  305. * @param encoding
  306. * @return the digest as a string
  307. * @throws UnsupportedEncodingException
  308. * @throws NoSuchAlgorithmException
  309. */
  310. public static String getDigestTypeEncoded(String plainTextString, String type, String encoding)
  311. throws UnsupportedEncodingException, NoSuchAlgorithmException {
  312. byte[] plainText = plainTextString.getBytes(encoding);
  313. MessageDigest messageDigest = MessageDigest.getInstance(type);
  314. messageDigest.update( plainText);
  315. return new String( messageDigest.digest(), encoding);
  316. }
  317. /**
  318. * Generates a digest using the DEFAULT_DIGEST and the DEFAULT_ENCODING
  319. *
  320. * @param plainTextString
  321. * @return the digest as a string
  322. * @throws UnsupportedEncodingException
  323. * @throws NoSuchAlgorithmException
  324. */
  325. public static String getDigest(String plainTextString)
  326. throws UnsupportedEncodingException, NoSuchAlgorithmException {
  327. return getDigestTypeEncoded(plainTextString, DEFAULT_DIGEST, DEFAULT_ENCODING);
  328. }
  329. }