001: /*
002: * $Id: CryptoModule.java,v 1.23 2002/09/16 08:05:02 jkl Exp $
003: *
004: * Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
005: *
006: * Use is subject to license terms, as defined in
007: * Anvil Sofware License, Version 1.1. See LICENSE
008: * file, or http://njet.org/license-1.1.txt
009: */
010: package anvil.core.crypto;
011:
012: import anvil.core.Any;
013: import anvil.core.AnyString;
014: import anvil.script.Context;
015: import com.sun.crypto.provider.SunJCE;
016: import java.security.Security;
017: import javax.crypto.Cipher;
018: import javax.crypto.SecretKey;
019: import javax.crypto.SecretKey;
020: import java.security.Provider;
021:
022: ///
023: /// @module CryptoModule
024: /// Digest and MAC codes, encryption.
025: ///
026: /// <h2>Digest and MAC codes</h2>
027: /// <p>
028: ///
029: /// Anvil crypto library can create message hash codes or checksums from any
030: /// data. Such codes are useful, for example, in payment applications,
031: /// where the checksum verifies that data has not been changed. Also the
032: /// hash codes taken from file contents are useful for checking if the
033: /// file content is changed or not.
034: ///
035: /// <ul>
036: /// <li>
037: /// <b>Message Digest</b> provides applications the functionality of
038: /// a message digest algorithm, such as MD5 or SHA. Message
039: /// digests are secure one-way hash functions that take arbitrary-sized
040: /// data and output a fixed-length hash value.
041: ///
042: /// <li>
043: /// <b>Message Authentication Code (MAC)</b><br>
044: /// Since everyone can generate the message digest,
045: /// it may not be suitable for some security related
046: /// applications. Because of this, Anvil also
047: /// supports HMAC (rfc2104), which is a mechanism for
048: /// message authentication using a (secret) key.
049: /// So you can use a key with a hash algorithm to
050: /// produce hashes that can only be verified using the same key.
051: /// </ul>
052: /// <p>
053: /// Example. Compute the MD5 digest and hmac and print them out as hex.<br>
054: /// <pre>
055: /// key = "Jefe";
056: /// data = "what do ya want for nothing?";
057: /// digest = crypto.MD5().update(data).final().toHex();
058: /// hmac = crypto.MD5(key).update(data).final().toHex();
059: /// print "The digest is "+digest;
060: /// print "The hmac is "+hmac;
061: /// </pre>
062: /// This will produce:
063: /// <pre>
064: /// The digest is d03cb659cbf9192dcd066272249f8412
065: /// The hmac is 750c783e6ab0b503eaa86e310a5db738
066: /// </pre>
067: ///
068: /// <h2>Encryption</h2>
069: /// <p>
070: /// Anvil crypto library can also encrypt and decrypt data using DES, TripleDes and
071: /// Blowfish algorithms.
072: ///
073: /// <p>
074: /// Example. Encrypt and decrypt a data string using DES.<br>
075: /// <pre>
076: /// key = "Jefe1234";
077: /// data1 = "what do ya want ";
078: /// data2 = "for nothing?";
079: /// cipher = crypto.encrypt(crypto.DES, key);
080: /// crypted = cipher.update(data1);
081: /// crypted = crypted.concat(cipher.update(data2));
082: /// crypted = crypted.concat(cipher.final());
083: /// recovered = crypto.decrypt(crypto.DES, key).final(crypted);
084: /// </pre>
085: ///
086: /// @author: Jaripekka Salminen
087: ///
088: public class CryptoModule {
089:
090: private static boolean initialized = false;
091:
092: /// @const DES DES algorithm
093: public static final Any DES = new AnyString("DES");
094:
095: /// @const TRIPLE_DES 3DES algorithm
096: public static final Any TRIPLE_DES = new AnyString("DESede");
097:
098: /// @const BLOWFISH Blowfish algorithm
099: public static final Any BLOWFISH = new AnyString("Blowfish");
100:
101: /// @function encrypt
102: /// @synopsis Cipher encrypt(string algorithm, object key)
103: /// @param algorithm should be one of supported algoritmhs such as
104: /// crypto.DES, crypto.TRIPLE_DES, crypto.BLOWFISH.
105: /// @param key string or binary key
106: /// @return a cipher object, which takes data and
107: /// then returns the encrypted data.
108: public static final Object[] p_encrypt = { null, "algorithm", "key" };
109:
110: public static final Any encrypt(Context context, String algrorithm,
111: Any key) {
112: init();
113: try {
114: return new AnyCipher(algrorithm, Cipher.ENCRYPT_MODE, key);
115: } catch (Exception e) {
116: throw context.exception(e);
117: }
118: }
119:
120: /// @function decrypt
121: /// @synopsis Cipher decrypt(string algorithm, object key)
122: /// @param algorithm should be one of supported algoritmhs such as
123: /// crypto.DES, crypto.TRIPLE_DES, crypto.BLOWFISH.
124: /// @param key string or binary key
125: /// @return a cipher object, which takes encrypted data and
126: /// then returns the original data.
127: public static final Object[] p_decrypt = { null, "algrorithm",
128: "key" };
129:
130: public static final Any decrypt(Context context, String algorithm,
131: Any key) {
132: init();
133: try {
134: return new AnyCipher(algorithm, Cipher.DECRYPT_MODE, key);
135: } catch (Exception e) {
136: throw context.exception(e);
137: }
138: }
139:
140: static void init() {
141: if (initialized) {
142: return;
143: }
144: /* Installs SunJCE provider */
145: Provider sunJce = new com.sun.crypto.provider.SunJCE();
146: Security.addProvider(sunJce);
147: initialized = true;
148: }
149:
150: public static final anvil.script.compiler.NativeNamespace __module__ = new anvil.script.compiler.NativeNamespace(
151: "crypto", CryptoModule.class,
152: new String[] { "anvil.core.crypto.AnyCipher",
153: "anvil.core.crypto.AnyMessageHash",
154: "anvil.core.crypto.AnyMD5",
155: "anvil.core.crypto.AnySHA", },
156: //DOC{{
157: ""
158: + "\n"
159: + " @module CryptoModule\n"
160: + " Digest and MAC codes, encryption.\n"
161: + " \n"
162: + " <h2>Digest and MAC codes</h2>\n"
163: + " <p>\n"
164: + " \n"
165: + " Anvil crypto library can create message hash codes or checksums from any\n"
166: + " data. Such codes are useful, for example, in payment applications,\n"
167: + " where the checksum verifies that data has not been changed. Also the\n"
168: + " hash codes taken from file contents are useful for checking if the\n"
169: + " file content is changed or not.\n"
170: + " \n"
171: + " <ul>\n"
172: + " <li>\n"
173: + " <b>Message Digest</b> provides applications the functionality of\n"
174: + " a message digest algorithm, such as MD5 or SHA. Message\n"
175: + " digests are secure one-way hash functions that take arbitrary-sized\n"
176: + " data and output a fixed-length hash value.\n"
177: + " \n"
178: + " <li>\n"
179: + " <b>Message Authentication Code (MAC)</b><br>\n"
180: + " Since everyone can generate the message digest,\n"
181: + " it may not be suitable for some security related\n"
182: + " applications. Because of this, Anvil also\n"
183: + " supports HMAC (rfc2104), which is a mechanism for\n"
184: + " message authentication using a (secret) key.\n"
185: + " So you can use a key with a hash algorithm to\n"
186: + " produce hashes that can only be verified using the same key.\n"
187: + " </ul>\n"
188: + " <p>\n"
189: + " Example. Compute the MD5 digest and hmac and print them out as hex.<br>\n"
190: + " <pre>\n"
191: + " key = \"Jefe\";\n"
192: + " data = \"what do ya want for nothing?\";\n"
193: + " digest = crypto.MD5().update(data).final().toHex();\n"
194: + " hmac = crypto.MD5(key).update(data).final().toHex();\n"
195: + " print \"The digest is \"+digest;\n"
196: + " print \"The hmac is \"+hmac;\n"
197: + " </pre>\n"
198: + " This will produce:\n"
199: + " <pre>\n"
200: + " The digest is d03cb659cbf9192dcd066272249f8412\n"
201: + " The hmac is 750c783e6ab0b503eaa86e310a5db738\n"
202: + " </pre>\n"
203: + " \n"
204: + " <h2>Encryption</h2>\n"
205: + " <p>\n"
206: + " Anvil crypto library can also encrypt and decrypt data using DES, TripleDes and\n"
207: + " Blowfish algorithms.\n"
208: + " \n"
209: + " <p>\n"
210: + " Example. Encrypt and decrypt a data string using DES.<br>\n"
211: + " <pre>\n"
212: + " key = \"Jefe1234\";\n"
213: + " data1 = \"what do ya want \";\n"
214: + " data2 = \"for nothing?\";\n"
215: + " cipher = crypto.encrypt(crypto.DES, key);\n"
216: + " crypted = cipher.update(data1);\n"
217: + " crypted = crypted.concat(cipher.update(data2));\n"
218: + " crypted = crypted.concat(cipher.final());\n"
219: + " recovered = crypto.decrypt(crypto.DES, key).final(crypted);\n"
220: + " </pre>\n"
221: + "\n"
222: + " @author: Jaripekka Salminen\n"
223: + "\n"
224: + " @const DES DES algorithm\n"
225: + " @const TRIPLE_DES 3DES algorithm\n"
226: + " @const BLOWFISH Blowfish algorithm\n"
227: + " @function encrypt\n"
228: + " @synopsis Cipher encrypt(string algorithm, object key) \n"
229: + " @param algorithm should be one of supported algoritmhs such as\n"
230: + " crypto.DES, crypto.TRIPLE_DES, crypto.BLOWFISH.\n"
231: + " @param key string or binary key\n"
232: + " @return a cipher object, which takes data and\n"
233: + " then returns the encrypted data.\n"
234: + " @function decrypt\n"
235: + " @synopsis Cipher decrypt(string algorithm, object key) \n"
236: + " @param algorithm should be one of supported algoritmhs such as\n"
237: + " crypto.DES, crypto.TRIPLE_DES, crypto.BLOWFISH.\n"
238: + " @param key string or binary key\n"
239: + " @return a cipher object, which takes encrypted data and\n"
240: + " then returns the original data.\n"
241: //}}DOC
242: );
243:
244: }
|