为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

Java加密技术

2012-07-09 50页 doc 985KB 26阅读

用户头像

is_355326

暂无简介

举报
Java加密技术加密算法分类 1.1 如基本的单向加密算法: A. BASE64 严格地说,属于编码格式,而非加密算法 B. MD5(Message Digest algorithm 5,信息摘要算法) C. SHA(Secure Hash Algorithm,安全散列算法) D. HMAC(Hash Message Authentication Code,散列消息鉴别码) 1.2 复杂的对称加密(DES、PBE)、非对称加密算法: A. DES(Data Encryption Standard,数据加密算法) B....
Java加密技术
加密算法分类 1.1 如基本的单向加密算法: A. BASE64 严格地说,属于编码,而非加密算法 B. MD5(Message Digest algorithm 5,信息摘要算法) C. SHA(Secure Hash Algorithm,安全散列算法) D. HMAC(Hash Message Authentication Code,散列消息鉴别码) 1.2 复杂的对称加密(DES、PBE)、非对称加密算法: A. DES(Data Encryption Standard,数据加密算法) B. PBE(Password-based encryption,基于密码验证) C. RSA(算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman) D. DH(Diffie-Hellman算法,密钥一致) E. DSA(Digital Signature Algorithm,数字签名) F. ECC(Elliptic Curves Cryptography,椭圆曲线密码编码学) 本篇内容简要介绍BASE64、MD5、SHA、HMAC几种方法。MD5、SHA、HMAC这三种加密算法,可谓是非可逆加密,就是不可解密的加密方法。我们通常只把他们作为加密的基础。单纯的以上三种的加密并不可靠。 BASE64 按照RFC2045的定义,Base64被定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式。(The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.) 常见于邮件、http加密,截取http信息,你就会发现登录操作的用户名、密码字段通过BASE64加密的。 Base64并不是一种加密算法,只能说是一种编码方式,并且是可逆的。 Base64原理图 通过java代码实现如下: Java代码 /**    * BASE64解密    *     * @param key    * @return    * @throws Exception    */   public static byte[] decryptBASE64(String key) throws Exception {        return (new BASE64Decoder()).decodeBuffer(key);    }       /**    * BASE64加密    *     * @param key    * @return    * @throws Exception    */   public static String encryptBASE64(byte[] key) throws Exception {        return (new BASE64Encoder()).encodeBuffer(key);    }   主要就是BASE64Encoder、BASE64Decoder两个类,我们只需要知道使用对应的方法即可。另,BASE加密后产生的字节位数是8的倍数,如果不够位数以=符号填充。 MD5(非可逆加密) MD5 -- message-digest algorithm 5 (信息-摘要算法)缩写,广泛用于加密和解密技术,常用于文件校验。校验?不管文件多大,经过MD5后都能生成唯一的MD5值。好比现在的ISO校验,都是MD5校验。怎么用?当然是把ISO经过MD5后产生MD5的值。一般下载linux-ISO的朋友都见过下载链接旁边放着MD5的串。就是用来验证文件是否一致的。 MD5加密原理图 通过java代码实现如下: Java代码 /**    * MD5加密    *     * @param data    * @return    * @throws Exception    */   public static byte[] encryptMD5(byte[] data) throws Exception {        MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);        md5.update(data);           return md5.digest();       }   通常我们不直接使用上述MD5加密。通常将MD5产生的字节数组交给BASE64再加密一把,得到相应的字符串。 SHA(安全散列算法) SHA(Secure Hash Algorithm,安全散列算法),数字签名等密码学应用中重要的工具,被广泛地应用于电子商务等信息安全领域。虽然,SHA与MD5通过碰撞法都被破解了, 但是SHA仍然是公认的安全加密算法,较之MD5更为安全。 SHA算法原理图 通过java代码实现如下: Java代码     /**        * SHA加密        *         * @param data        * @return        * @throws Exception        */       public static byte[] encryptSHA(byte[] data) throws Exception {            MessageDigest sha = MessageDigest.getInstance(KEY_SHA);            sha.update(data);            return sha.digest();        }    }   } HMAC HMAC(Hash Message Authentication Code),散列消息鉴别码,基于密钥的Hash算法的认证协议。消息鉴别码实现鉴别的原理是,用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证等。 HSMAC原理图 通过java代码实现如下: Java代码 /**    * 初始化HMAC密钥    *     * @return    * @throws Exception    */   public static String initMacKey() throws Exception {        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);           SecretKey secretKey = keyGenerator.generateKey();        return encryptBASE64(secretKey.getEncoded());    }       /**    * HMAC加密    *     * @param data    * @param key    * @return    * @throws Exception    */   public static byte[] encryptHMAC(byte[] data, String key) throws Exception {           SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);        Mac mac = Mac.getInstance(secretKey.getAlgorithm());        mac.init(secretKey);           return mac.doFinal(data);       }   给出一个完整类,如下: Java代码 import java.security.MessageDigest;       import javax.crypto.KeyGenerator;    import javax.crypto.Mac;    import javax.crypto.SecretKey;       import sun.misc.BASE64Decoder;    import sun.misc.BASE64Encoder;       /**    * 基础加密组件    *     * @author 梁栋    * @version 1.0    * @since 1.0    */   public abstract class Coder {        public static final String KEY_SHA = "SHA";        public static final String KEY_MD5 = "MD5";           /**        * MAC算法可选以下多种算法        *         * 
  

     * HmacMD5   

     * HmacSHA1   

     * HmacSHA256   

     * HmacSHA384   

     * HmacSHA512  

     * 
       */       public static final String KEY_MAC = "HmacMD5";           /**        * BASE64解密        *         * @param key        * @return        * @throws Exception        */       public static byte[] decryptBASE64(String key) throws Exception {            return (new BASE64Decoder()).decodeBuffer(key);        }           /**        * BASE64加密        *         * @param key        * @return        * @throws Exception        */       public static String encryptBASE64(byte[] key) throws Exception {            return (new BASE64Encoder()).encodeBuffer(key);        }           /**        * MD5加密        *         * @param data        * @return        * @throws Exception        */       public static byte[] encryptMD5(byte[] data) throws Exception {               MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);            md5.update(data);               return md5.digest();           }           /**        * SHA加密        *         * @param data        * @return        * @throws Exception        */       public static byte[] encryptSHA(byte[] data) throws Exception {               MessageDigest sha = MessageDigest.getInstance(KEY_SHA);            sha.update(data);               return sha.digest();           }           /**        * 初始化HMAC密钥        *         * @return        * @throws Exception        */       public static String initMacKey() throws Exception {            KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);               SecretKey secretKey = keyGenerator.generateKey();            return encryptBASE64(secretKey.getEncoded());        }           /**        * HMAC加密        *         * @param data        * @param key        * @return        * @throws Exception        */       public static byte[] encryptHMAC(byte[] data, String key) throws Exception {               SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);            Mac mac = Mac.getInstance(secretKey.getAlgorithm());            mac.init(secretKey);               return mac.doFinal(data);           }    }   再给出一个测试类: Java代码 import static org.junit.Assert.*;     import org.junit.Test;    /**    *     * @author 梁栋    * @version 1.0    * @since 1.0    */   public class CoderTest {           @Test       public void test() throws Exception {            String inputStr = "简单加密";            System.err.println("原文:\n" + inputStr);               byte[] inputData = inputStr.getBytes();            String code = Coder.encryptBASE64(inputData);               System.err.println("BASE64加密后:\n" + code);               byte[] output = Coder.decryptBASE64(code);               String outputStr = new String(output);               System.err.println("BASE64解密后:\n" + outputStr);               // 验证BASE64加密解密一致性            assertEquals(inputStr, outputStr);               // 验证MD5对于同一内容加密是否一致            assertArrayEquals(Coder.encryptMD5(inputData), Coder .encryptMD5(inputData));               // 验证SHA对于同一内容加密是否一致            assertArrayEquals(Coder.encryptSHA(inputData), Coder                    .encryptSHA(inputData));               String key = Coder.initMacKey();            System.err.println("Mac密钥:\n" + key);               // 验证HMAC对于同一内容,同一密钥加密是否一致            assertArrayEquals(Coder.encryptHMAC(inputData, key), Coder.encryptHMAC(                    inputData, key));               BigInteger md5 = new BigInteger(Coder.encryptMD5(inputData));            System.err.println("MD5:\n" + md5.toString(16));               BigInteger sha = new BigInteger(Coder.encryptSHA(inputData));            System.err.println("SHA:\n" + sha.toString(32));               BigInteger mac = new BigInteger(Coder.encryptHMAC(inputData, inputStr));            System.err.println("HMAC:\n" + mac.toString(16));        }    }   控制台输出: Console代码 原文:    简单加密    BASE64加密后:    566A5Y2V5Yqg5a+G       BASE64解密后:    简单加密    Mac密钥:    uGxdHC+6ylRDaik++leFtGwiMbuYUJ6mqHWyhSgF4trVkVBBSQvY/a22xU8XT1RUemdCWW155Bke    pBIpkd7QHg==       MD5:    -550b4d90349ad4629462113e7934de56    SHA:    91k9vo7p400cjkgfhjh0ia9qthsjagfn    HMAC:    2287d192387e95694bdbba2fa941009a   原文: 简单加密 BASE64加密后: 566A5Y2V5Yqg5a+G BASE64解密后: 简单加密 Mac密钥: uGxdHC+6ylRDaik++leFtGwiMbuYUJ6mqHWyhSgF4trVkVBBSQvY/a22xU8XT1RUemdCWW155Bke pBIpkd7QHg== MD5: -550b4d90349ad4629462113e7934de56 SHA: 91k9vo7p400cjkgfhjh0ia9qthsjagfn HMAC: 2287d192387e95694bdbba2fa941009a 注意 编译时,可能会看到如下提示: 引用 警告:sun.misc.BASE64Decoder 是 Sun 的专用 API,可能会在未来版本中删除 import sun.misc.BASE64Decoder;                ^ 警告:sun.misc.BASE64Encoder 是 Sun 的专用 API,可能会在未来版本中删除 import sun.misc.BASE64Encoder;                ^ BASE64Encoder和BASE64Decoder是非官方JDK实现类。虽然可以在JDK里能找到并使用,但是在API里查不到。JRE中sun和com.sun开头包的类都是未被文档化的,他们属于java, javax 类库的基础,其中的实现大多数与底层平台有关,一般来说是不推荐使用的。     BASE64的加密解密是双向的,可以求反解。MD5、SHA以及HMAC是单向加密,任何数据加密后只会产生唯一的一个加密串,通常用来校验数据在传输过程中是否被修改。其中HMAC算法有一个密钥,增强了数据传输过程中的安全性,强化了算法外的不可控因素。单向加密的用途主要是为了校验数据在传输过程中是否被修改。 接下来我们介绍对称加密算法,最常用的莫过于DES数据加密算法。 DES DES-Data Encryption Standard,即数据加密算法。是IBM公司于1975年研究成功并公开发表的。DES算法的入口参数有三个:Key、Data、Mode。其中Key为8个字节共64位,是DES算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。   DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位。 通过java代码实现如下:Coder类见 Java加密技术(一) Java代码 import java.security.Key;    import java.security.SecureRandom;       import javax.crypto.Cipher;    import javax.crypto.KeyGenerator;    import javax.crypto.SecretKey;    import javax.crypto.SecretKeyFactory;    import javax.crypto.spec.DESKeySpec;          /**    * DES安全编码组件    *     * 
  

 * 支持 DES、DESede(TripleDES,就是3DES)、AES、Blowfish、RC2、RC4(ARCFOUR)  

 * DES                  key size must be equal to 56  

 * DESede(TripleDES)    key size must be equal to 112 or 168  

 * AES                  key size must be equal to 128, 192 or 256,but 192 and 256 bits may not be available  

 * Blowfish             key size must be multiple of 8, and can only range from 32 to 448 (inclusive)  

 * RC2                  key size must be between 40 and 1024 bits  

 * RC4(ARCFOUR)         key size must be between 40 and 1024 bits  

 * 具体内容 需要关注 JDK Document http://.../docs/technotes/guides/security/SunProviders.html  

 * 
   *     * @author 梁栋    * @version 1.0    * @since 1.0    */   public abstract class DESCoder extends Coder {        /**        * ALGORITHM 算法 
       * 可替换为以下任意一种算法,同时key值的size相应改变。        *         * 
  

     * DES                  key size must be equal to 56  

     * DESede(TripleDES)    key size must be equal to 112 or 168  

     * AES                  key size must be equal to 128, 192 or 256,but 192 and 256 bits may not be available  

     * Blowfish             key size must be multiple of 8, and can only range from 32 to 448 (inclusive)  

     * RC2                  key size must be between 40 and 1024 bits  

     * RC4(ARCFOUR)         key size must be between 40 and 1024 bits  

     * 
       *         * 在Key toKey(byte[] key)方法中使用下述代码        * SecretKey secretKey = new SecretKeySpec(key, ALGORITHM); 替换        *         * DESKeySpec dks = new DESKeySpec(key);        * SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);        * SecretKey secretKey = keyFactory.generateSecret(dks);        *         */       public static final String ALGORITHM = "DES";           /**        * 转换密钥
       *         * @param key        * @return        * @throws Exception        */       private static Key toKey(byte[] key) throws Exception {            DESKeySpec dks = new DESKeySpec(key);            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);            SecretKey secretKey = keyFactory.generateSecret(dks);               // 当使用其他对称加密算法时,如AES、Blowfish等算法时,用下述代码替换上述三行代码            // SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);               return secretKey;        }           /**        * 解密        *         * @param data        * @param key        * @return        * @throws Exception        */       public static byte[] decrypt(byte[] data, String key) throws Exception {            Key k = toKey(decryptBASE64(key));               Cipher cipher = Cipher.getInstance(ALGORITHM);            cipher.init(Cipher.DECRYPT_MODE, k);               return cipher.doFinal(data);        }          /**        * 生成密钥        *         * @return        * @throws Exception        */       public static String initKey() throws Exception {            return initKey(null);        }           /**        * 生成密钥        *         * @param seed        * @return        * @throws Exception        */       public static String initKey(String seed) throws Exception {            SecureRandom secureRandom = null;               if (seed != null) {                secureRandom = new SecureRandom(decryptBASE64(seed));            } else {                secureRandom = new SecureRandom();            }               KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM);            kg.init(secureRandom);               SecretKey secretKey = kg.generateKey();               return encryptBASE64(secretKey.getEncoded());        }    }   import java.security.Key; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; 延续上一个类的实现,我们通过MD5以及SHA对字符串加密生成密钥,这是比较常见的密钥生成方式。 再给出一个测试类: Java代码 import static org.junit.Assert.*;    import org.junit.Test;       /**    *     * @author 梁栋    * @version 1.0    * @since 1.0    */   public class DESCoderTest {           @Test       public void test() throws Exception {            String inputStr = "DES";            String key = DESCoder.initKey();            System.err.println("原文:\t" + inputStr);               System.err.println("密钥:\t" + key);               byte[] inputData = inputStr.getBytes();            inputData = DESCoder.encrypt(inputData, key);               System.err.println("加密后:\t" + DESCoder.encryptBASE64(inputData));               byte[] outputData = DESCoder.decrypt(inputData, key);            String outputStr = new String(outputData);               System.err.println("解密后:\t" + outputStr);               assertEquals(inputStr, outputStr);        }    }   得到的输出内容如下: Console代码 原文: DES    密钥: f3wEtRrV6q0=    加密后:    C6qe9oNIzRY=    解密后:    DES   原文: DES 密钥: f3wEtRrV6q0= 加密后: C6qe9oNIzRY= 解密后: DES     由控制台得到的输出,我们能够比对加密、解密后结果一致。这是一种简单的加密解密方式,只有一个密钥。     其实DES有很多同胞兄弟,如DESede(TripleDES)、AES、Blowfish、RC2、RC4(ARCFOUR)。这里就不过多阐述了,大同小异,只要换掉ALGORITHM换成对应的值,同时做一个代码替换SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);就可以了,此外就是密钥长度不同了。 Java代码 /**    * DES          key size must be equal to 56    * DESede(TripleDES) key size must be equal to 112 or 168    * AES          key size must be equal to 128, 192 or 256,but 192 and 256 bits may not be available    * Blowfish     key size must be multiple of 8, and can only range from 32 to 448 (inclusive)    * RC2          key size must be between 40 and 1024 bits    * RC4(ARCFOUR) key size must be between 40 and 1024 bits    **/   /** * DES key size must be equal to 56 * DESede(TripleDES) key size must be equal to 112 or 168 * AES key size must be equal to 128, 192 or 256,but 192 and 256 bits may not be available * Blowfish key size must be multiple of 8, and can only range from 32 to 448 (inclusive) * RC2 key size must be between 40 and 1024 bits * RC4(ARCFOUR) key size must be between 40 and 1024 bits **/ 除了DES,我们还知道有DESede(TripleDES,就是3DES)、AES、Blowfish、RC2、RC4(ARCFOUR)等多种对称加密方式,其实现方式大同小异,这里介绍对称加密的另一个算法——PBE。 PBE PBE——Password-based encryption(基于密码加密)。其特点在于口令由用户自己掌管,不借助任何物理媒体;采用随机数(这里我们叫做盐)杂凑多重加密等方法保证数据的安全性。是一种简便的加密方式。 通过java代码实现如下:Coder类见 Java代码 import java.security.Key;    import java.util.Random;       import javax.crypto.Cipher;    import javax.crypto.SecretKey;    import javax.crypto.SecretKeyFactory;    import javax.crypto.spec.PBEKeySpec;    import javax.crypto.spec.PBEParameterSpec;       /**    * PBE安全编码组件    *     * @author 梁栋    * @version 1.0    * @since 1.0    */   public abstract class PBECoder extends Coder {        /**        * 支持以下任意一种算法        *         * 
  

     * PBEWithMD5AndDES   

     * PBEWithMD5AndTripleDES   

     * PBEWithSHA1AndDESede  

     * PBEWithSHA1AndRC2_40  

     * 
       */       public static final String ALGORITHM = "PBEWITHMD5andDES";           /**        * 盐初始化        *         * @return        * @throws Exception        */       public static byte[] initSalt() throws Exception {            byte[] salt = new byte[8];            Random random = new Random();            random.nextBytes(salt);            return salt;        }           /**        * 转换密钥
       *         * @param password        * @return        * @throws Exception        */       private static Key toKey(String password) throws Exception {            PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);            SecretKey secretKey = keyFactory.generateSecret(keySpec);               return secretKey;        }           /**        * 加密        *         * @param data        *            数据        * @param password        *            密码        * @param salt        *            盐        * @return        * @throws Exception        */       public static byte[] encrypt(byte[] data, String password, byte[] salt)                throws Exception {               Key key = toKey(password);               PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);            Cipher cipher = Cipher.getInstance(ALGORITHM);            cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);               return cipher.doFinal(data);           }           /**        * 解密        *         * @param data        *            数据        * @param password        *            密码        * @param salt        *            盐        * @return        * @throws Exception        */       public static byte[] decrypt(byte[] data, String password, byte[] salt)                throws Exception {               Key key = toKey(password);               PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);            Cipher cipher = Cipher.getInstance(ALGORITHM);            cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);               return cipher.doFinal(data);           }    }   再给出一个测试类: Java代码 import static org.junit.Assert.*;       import org.junit.Test;       /**    *     * @author 梁栋    * @version 1.0    * @since 1.0    */   public class PBECoderTest {           @Test       public void test() throws Exception {            String inputStr = "abc";            System.err.println("原文: " + inputStr);            byte[] input = inputStr.getBytes();               String pwd = "efg";            System.err.println("密码: " + pwd);               byte[] salt = PBECoder.initSalt();               byte[] data = PBECoder.encrypt(input, pwd, salt);               System.err.println("加密后: " + PBECoder.encryptBASE64(data));               byte[] output = PBECoder.decrypt(data, pwd, salt);            String outputStr = new String(output);               System.err.println("解密后: " + outputStr);            assertEquals(inputStr, outputStr);        }       }   控制台输出: Console代码 原文: abc    密码: efg    加密后: iCZ0uRtaAhE=    解密后: abc   原文: abc 密码: e
/
本文档为【Java加密技术】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索