DES(Data Encryption Standard)又叫数据加密标准,是1973年5月15日美国国家标准局(现在是美国标准技术研究所,即NIST)在联邦记录中公开征集密码体制时出现的。DES由IBM开发,它是对早期被称为Lucifer体制的改进。DES在1975年3月17日首次在联邦记录中公布,在经过大量的公开讨论后,1977年2月15日DES被采纳为“非密级”应用的一个标准。最初预期DES作为一个标准只能使用10-15年,然而,事实证明DES要长寿得多。在其被采用后,大约每隔5年被评审一次。DES的最后一次评审是在1999年1月,在当时,一个DES的替代品,AES(Advanced Encryption Standard)开始使用。
DES是一种分组对称加解密算法,用64位密钥(实际用56位,其中每第八位作奇偶校验位)来加密(解密)64位数据,加密的过程伴随一系列的转换与代换操作。DES加密(解密)的过程可以分为两步:首先变换密钥得到56位密钥,然后据转换操作得到48位共16组子密钥。其次是用上面得到的16组子密钥加密(解密) 64位明(密)文,这个过程会有相应的S-BOX等的代换-转换操作。整个算法加密过程可以参考DES标准说明文件。
js代码(源代码见尾部附件(des.zip))
注意:js加载顺序依次为 jquery.js,cryptojs-core.js,enc-base64.js,cipher-core.js,tripledes.js,mode-ecb.js
Insert title here DES Demo.
java代码
Des.java
import java.security.Key; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; /** * DES(Data Encryption Standard, 数据加密标准).
* Key为64位,去除64位中作为奇偶校验位的第8、16、24、32、40、48、56、64位,剩下的56位作为有效输入密钥.
* @author jason.zhong
* @version 1.0.0 2016年6月30日
* @see */ public class Des { /** * 日志记录器. */ // private static Log LOG = LogFactory.getLog(Des.class); /** * DES加解密算法. */ protected static final String ALGORITHM_DES = "DES"; /** * DES填补方式. * DES/CBC/PKCS5Padding. */ protected static final String TRANSFORMATION_DES = "DES/ECB/Pkcs7"; /** * 构造函数(私有). * @param algorithm 算法 * @param transformation 转换方式 */ private Des(String algorithm, String transformation) { } /** * 加密算法. * @param data 需要加密的数据 * @param key 秘钥 * @return */ public static String encryptAsString(String data, String key) { byte[] bt = Des.encrypt(data.getBytes(), key.getBytes()); return Base64.encryptAsString(bt); } /** * 解密算法. * @param data 需要解密的数据 * @param key 秘钥 * @return */ public static byte[] decryptAsByteArray(String data, String key) { if (data == null) return null; byte[] buf = Base64.decryptAsByteArray(data); return decrypt(buf, key.getBytes()); } /** * 解密算法 * @param data 需要解密的数据 * @param key 秘钥 * @return */ public static String decryptAsString(String data, String key) { if (data == null) { return null; } byte[] bt = decryptAsByteArray(data, key); return new String(bt); } /** * * @param data * @param key * @return */ private static byte[] encrypt(byte[] data, byte[] key) { return doFinal(data, key, ALGORITHM_DES, TRANSFORMATION_DES, Cipher.ENCRYPT_MODE); } /** * * @param data * @param key * @return */ private static byte[] decrypt(byte[] data, byte[] key) { return doFinal(data, key, ALGORITHM_DES, TRANSFORMATION_DES, Cipher.DECRYPT_MODE); } /** * 加密/解密操作. * @param data 需要操作的数据 * @param key 秘钥 * @param algorithm * @param transformation * @param opmode * @return * @throws Exception */ private static byte[] doFinal(byte[] data, byte[] key, String algorithm, String transformation, int opmode) { byte[] result = null; try { // 创建秘钥工厂 // final SecretKey securekey = new SecretKeySpec(key, algorithm); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); Key key2 = keyFactory.generateSecret(new DESKeySpec(key)); // 加密/解密 final SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); final Cipher cipher = Cipher.getInstance("DES"); // transformation : the name of the transformation, e.g., DES/CBC/PKCS5Padding. cipher.init(opmode, key2, secureRandom); result = cipher.doFinal(data); } catch (Exception e) { // if (LOG.isErrorEnabled()) { // LOG.error(new ExampleRuntimeException(e)); // } } return result; } public static void main(String[] args) { final String plainText = "武汉 湖北 中国"; final String key = "AAAABBBB"; final String decodedText = Des.encryptAsString(plainText, key); System.out.println(decodedText); final String encodeText = Des.decryptAsString(decodedText, key); System.out.println(encodeText); } }
Base64.java
/** * Base加解密.
* @author jason.zhong
* @version 1.0.0 2016年6月30日
* @see * @since JDK 1.6.0 */ public class Base64 { public static byte[] encryptAsByteArray(byte[] plainData) { return org.apache.commons.codec.binary.Base64.encodeBase64(plainData); } public static String encryptAsString(byte[] plainData) { final byte[] base64Data = encryptAsByteArray(plainData); return StringUtil.toUtf8String(base64Data); } public static byte[] encryptAsByteArray(String plainText) { final byte[] plainData = plainText.getBytes(); return encryptAsByteArray(plainData); } public static String encryptAsString(String plainText) { final byte[] plainData = plainText.getBytes(); return encryptAsString(plainData); } public static byte[] decryptAsByteArray(String base64String) { return org.apache.commons.codec.binary.Base64.decodeBase64(base64String.getBytes()); } public static String decryptAsString(String base64String) { byte[] plainData = decryptAsByteArray(base64String); return StringUtil.toUtf8String(plainData); } public static void main(String[] args) { final String s = "武汉 湖北 中国"; System.out.println(encryptAsString(s)); System.out.println(decryptAsString(encryptAsString(s))); } }
StringUtil.java
import java.io.UnsupportedEncodingException; /** * 字符串工具类.
* @author jason.zhong
*/ public final class StringUtil { /** * 斜线. */ public static final char SLASH = '\u002f'; /** * 反斜线. */ public static final char BACK_SLASH = '\\'; /** * 点号. */ public static final char DOT = '\u002e'; /** * 逗号. */ public static final char COMMA = '\u002c'; /** * 空字符串"". */ public static final char EMPTY = '\u0000'; /** * 空格. */ public static final char SPACE = '\u0020'; /** * 左中括号. */ public static final char LEFT_BRACKET = '\u005b'; /** * 左中括号. */ public static final char RIGHT_BRACKET = '\u005d'; /** * UTF-8 */ public static final String UTF_8 = "UTF-8"; /** * GBK */ public static final String GBK = "GBK"; /** * GB231 */ public static final String GB2312 = "GB2312"; /** * 构造函数(私有) */ private StringUtil() { } /** * 判断字符串是否是null或者空字符串. * @param s 被判断的字符串 * @return 如果字符串为null或""则返回true,否则返回false. */ public static boolean hasText(String s) { if (null == s || s.length() == 0) { return false; } else { return true; } } /** * 根据Field的名字,按照Bean的规则,生产对应的Setter方法名. * @param fieldName field名称 * @return Setter方法名称 */ public static String getGetterMethodName(final String fieldName) { return "get" + upperCaseFirst(fieldName); } /** * 根据Field的名字,按照Bean的规则,生产对应的Setter方法名. * @param fieldName field名称 * @return Setter方法名称 */ public static String getSetterMethodName(final String fieldName) { return "set" + upperCaseFirst(fieldName); } /** * 将字符串的首字母变为大写. * @param s * @return */ public static String upperCaseFirst(final String s) { if (null == s || s.length() < 1) { return s; } return s.substring(0, 1).toUpperCase() + s.substring(1, s.length()); } /** * 将字符串的首字母变为小写. * @param s * @return */ public static String lowerCaseFirst(final String s) { if (null == s || s.length() < 1) { return s; } return s.substring(0, 1).toLowerCase() + s.substring(1, s.length()); } /** * 格式化字符串. * 将字符串中的{1}、{2}替换成%s,便于使用String.format方法. * @param message * @param arguments */ public static String formatString(String messages, Object... arguments) { final String regExp = "\\{\\d+\\}"; return String.format(messages.replaceAll(regExp, "%s"), arguments); } /** * 格式化字符串数组. * @param message * @param arguments */ public static String formatStringArray(String[] messages, Object... arguments) { if (null == messages || messages.length == 0) { return String.valueOf(EMPTY); } final StringBuilder sbMessage = new StringBuilder(); for (int i=0; i < messages.length; i++) { sbMessage.append(messages[i]); if (i < messages.length - 1) { sbMessage.append(COMMA); sbMessage.append(SPACE); } else { sbMessage.append(DOT); } } return formatString(sbMessage.toString(), arguments); } /** * 判断字符串转换为全小写后,是否为"true". * @param s * @return 如果指定的字符串不为空,而且忽略大小写后等于"true",那么返回true,否则返回false. */ public static boolean isTrue(String s) { return (s != null) && s.equalsIgnoreCase("true"); } /** * 将btye转化为UTF-8格式的字符串. * @param data * @return */ public static String toUtf8String(byte[] data) { String result = ""; try { result = new String(data, UTF_8); } catch (UnsupportedEncodingException e) { // 这个异常不会产生. } return result; } }