博客
关于我
常用Java密码技术
阅读量:498 次
发布时间:2019-03-07

本文共 15468 字,大约阅读时间需要 51 分钟。

著名的密码学者Ron Rivest曾经说过:“密码学是关于如何在敌人存在的环境中通讯”。

的确,从严谨的角度来讲,不管是公网环境还是在企业内网,我们设计系统的时候都需要充分考虑通讯安全。以下总结了一些常用的java密码技术,供参考。

1,单向散列函数

又称单向Hash函数、杂凑函数,就是把任意长的输入消息串变化成固定长的输出串且由输出串难以得到输入串的一种函数。这个输出串称为该消息的散列值。一般用于产生消息摘要,密钥加密等.

1)MD5

是RSA数据安全公司开发的一种单向散列算法,MD5被广泛使用。MD5的强抗碰撞性目前已被破解。
代码示例:

package com.huangzi.demo;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;public class MD5 {        public static byte[] eccrypt(String info) throws NoSuchAlgorithmException{          //获取MD5的MessageDigest对象          MessageDigest md5 = MessageDigest.getInstance("MD5");          byte[] srcBytes = info.getBytes();          md5.update(srcBytes);          byte[] resultBytes = md5.digest();          return resultBytes;      }      public static void main(String args[]) throws NoSuchAlgorithmException{          String msg = "皇子——常用java密码技术";          byte[] resultBytes = MD5.eccrypt(msg);          System.out.println("密文:" + new String(resultBytes));          System.out.println("明文:" + msg);      }  }

2)SHA

分为SHA-1,SHA-224,SHA-256,SHA-384。目前SHA-1的强抗碰撞性已被破解。

package com.huangzi.demo;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;public class SHA {           public static byte[] eccrypt(String shaType,String info) throws NoSuchAlgorithmException{              MessageDigest md5 = MessageDigest.getInstance(shaType);              byte[] srcBytes = info.getBytes();              md5.update(srcBytes);              byte[] resultBytes = md5.digest();              return resultBytes;          }          /**          * @param args          * @throws NoSuchAlgorithmException           */          public static void main(String[] args) throws NoSuchAlgorithmException {              String msg = "皇子讲java密码技术";              String[] shaTypes = new String[] { "SHA1", "SHA-256", "SHA-384", "SHA-512" };             for(String shaType : shaTypes) {                System.out.println(shaType);                byte[] resultBytes = SHA.eccrypt(shaType,msg);                  System.out.println("明文:" + msg);                  System.out.println("密文:" + new String(resultBytes));                System.out.println("========================");            }        }}

2,对称加密

一种加密与解密用的是相同的密钥的加密方式。

1)DES
DES,全称为“Data Encryption Standard”,中文名为“数据加密标准”,是一种使用密钥加密的块算法。1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。

import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;public class DES {       private KeyGenerator keygen;      private SecretKey deskey;      private Cipher cipher;      private byte[] cipherByte;      public DES() throws NoSuchAlgorithmException, NoSuchPaddingException{          keygen = KeyGenerator.getInstance("DES");          deskey = keygen.generateKey();          cipher = Cipher.getInstance("DES");      }      public byte[] Encrytor(String str) throws InvalidKeyException,              IllegalBlockSizeException, BadPaddingException {          cipher.init(Cipher.ENCRYPT_MODE, deskey);          byte[] src = str.getBytes();          cipherByte = cipher.doFinal(src);          return cipherByte;      }      public byte[] Decryptor(byte[] buff) throws InvalidKeyException,              IllegalBlockSizeException, BadPaddingException {          cipher.init(Cipher.DECRYPT_MODE, deskey);          cipherByte = cipher.doFinal(buff);          return cipherByte;      }      public static void main(String[] args) throws Exception {          DES de1 = new DES();          String msg ="皇子讲java密码技术";          byte[] encontent = de1.Encrytor(msg);          byte[] decontent = de1.Decryptor(encontent);          System.out.println("明文:" + msg);          System.out.println("密文:" + new String(encontent));          System.out.println("解密:" + new String(decontent));      } }

2)3DES

又称Triple DES,是DES加密算法的一种模式,它使用3条56位的密钥对3DES数据进行三次加密。

package com.huangzi.demo;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;public class DESDESDES {       private KeyGenerator keygen;      private SecretKey deskey;      private Cipher c;      private byte[] cipherByte;      public DESDESDES() throws NoSuchAlgorithmException, NoSuchPaddingException {          keygen = KeyGenerator.getInstance("DESede");          deskey = keygen.generateKey();          c = Cipher.getInstance("DESede");      }      /**      * 加密      *       * @param str      * @return      * @throws InvalidKeyException      * @throws IllegalBlockSizeException      * @throws BadPaddingException      */      public byte[] Encrytor(String str) throws InvalidKeyException,              IllegalBlockSizeException, BadPaddingException {          c.init(Cipher.ENCRYPT_MODE, deskey);          byte[] src = str.getBytes();          cipherByte = c.doFinal(src);          return cipherByte;      }      /**      * 解密      *       * @param buff      * @return      * @throws InvalidKeyException      * @throws IllegalBlockSizeException      * @throws BadPaddingException      */      public byte[] Decryptor(byte[] buff) throws InvalidKeyException,              IllegalBlockSizeException, BadPaddingException {          c.init(Cipher.DECRYPT_MODE, deskey);          cipherByte = c.doFinal(buff);          return cipherByte;      }      /**      * @param args      * @throws NoSuchPaddingException       * @throws NoSuchAlgorithmException       * @throws BadPaddingException       * @throws IllegalBlockSizeException       * @throws InvalidKeyException       */      public static void main(String[] args) throws Exception {          DESDESDES des = new DESDESDES();          String msg ="皇子讲java密码技术";          byte[] encontent = des.Encrytor(msg);          byte[] decontent = des.Decryptor(encontent);          System.out.println("明文:" + msg);          System.out.println("密文:" + new String(encontent));          System.out.println("解密:" + new String(decontent));      } }

3)AES

高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。由美国国家标准与技术研究院(NIST)发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。是对称密钥加密中最流行的算法之一。

package com.huangzi.demo;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;public class AES {       private KeyGenerator keygen;      private SecretKey deskey;      private Cipher cipher;      private byte[] cipherByte;      public AES() throws NoSuchAlgorithmException, NoSuchPaddingException{          keygen = KeyGenerator.getInstance("AES");          deskey = keygen.generateKey();          cipher = Cipher.getInstance("AES");      }      /**      * 加密      * @param str      * @return      * @throws InvalidKeyException      * @throws IllegalBlockSizeException      * @throws BadPaddingException      */      public byte[] Encrytor(String str) throws InvalidKeyException,              IllegalBlockSizeException, BadPaddingException {          cipher.init(Cipher.ENCRYPT_MODE, deskey);          byte[] src = str.getBytes();          cipherByte = cipher.doFinal(src);          return cipherByte;      }      /**      * 解密      * @param buff      * @return      * @throws InvalidKeyException      * @throws IllegalBlockSizeException      * @throws BadPaddingException      */      public byte[] Decryptor(byte[] buff) throws InvalidKeyException,              IllegalBlockSizeException, BadPaddingException {          cipher.init(Cipher.DECRYPT_MODE, deskey);          cipherByte = cipher.doFinal(buff);          return cipherByte;      }      /**      * @param args      * @throws NoSuchPaddingException       * @throws NoSuchAlgorithmException       * @throws BadPaddingException       * @throws IllegalBlockSizeException       * @throws InvalidKeyException       */      public static void main(String[] args) throws Exception {          AES aes = new AES();          String msg ="皇子讲java密码技术";          byte[] encontent = aes.Encrytor(msg);          byte[] decontent = aes.Decryptor(encontent);          System.out.println("明文:" + msg);          System.out.println("密文:" + new String(encontent));          System.out.println("解密:" + new String(decontent));      }  }

4)PBE

PBE算法(Password Based Encryption,基于口令加密)是一种基于口令的加密算法,其特点是使用口令代替了密钥,而口令由用户自己掌管,采用随机数杂凑多重加密等方法保证数据的安全性。
PBE算法在加密过程中并不是直接使用口令来加密,而是加密的密钥由口令生成,这个功能由PBE算法中的KDF函数完成。KDF函数的实现过程为:将用户输入的口令首先通过“盐”(salt)的扰乱产生准密钥,再将准密钥经过散列函数多次迭代后生成最终加密密钥,密钥生成后,PBE算法再选用对称加密算法对数据进行加密,可以选择DES、3DES、RC5等对称加密算法。

package com.huangzi.demo;import java.security.InvalidAlgorithmParameterException;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;import java.security.spec.InvalidKeySpecException;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;import javax.crypto.SecretKeyFactory;import javax.crypto.spec.PBEKeySpec;import javax.crypto.spec.PBEParameterSpec;public class PEB {       private static Cipher cipher;    private static SecretKey generateKey;    private static PBEParameterSpec pbeParameterSpec;    public static byte[] encode(String src) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, InvalidKeyException, InvalidAlgorithmParameterException{        SecureRandom secureRandom = new SecureRandom();        byte[] salt = secureRandom.generateSeed(8);        String password = "abc123";        PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());        SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBEWITHMD5andDES");        generateKey = secretKeyFactory.generateSecret(pbeKeySpec);        pbeParameterSpec = new PBEParameterSpec(salt, 100);        cipher = Cipher.getInstance("PBEWITHMD5andDES");        cipher.init(Cipher.ENCRYPT_MODE, generateKey, pbeParameterSpec);        return cipher.doFinal(src.getBytes());    }    public static byte[] decode(byte[] src) throws InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException{            cipher.init(Cipher.DECRYPT_MODE, generateKey, pbeParameterSpec);            return cipher.doFinal(src);    }    public static void main(String[] args) throws Exception{        String msg ="皇子讲java密码技术";          byte[] encontent = PEB.encode(msg);        byte[] decontent = PEB.decode(encontent);        System.out.println("明文:" + msg);          System.out.println("密文:" + new String(encontent));          System.out.println("解密:" + new String(decontent));       }}

3,公钥密码

公钥密码又称为非对称密码,拥有公钥密码的用户分别拥有加密密钥和解密密钥。通过加密密钥不能得到解密密钥。并且加密密钥是公开的。
解密密钥一开始就由接收者自己保管,可以解决密钥配送的问题

1)RSA

1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。1987年7月首次在美国公布,当时他们三人都在麻省理工学院工作实习。RSA就是他们三人姓氏开头字母拼在一起组成的。
RSA是目前最有影响力和最常用的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。
今天只有短的RSA钥匙才可能被强力方式解破。到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。
但在分布式计算和量子计算机理论日趋成熟的今天,RSA加密安全性受到了挑战和质疑。

package com.huangzi.demo;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import javax.crypto.Cipher;public class RSA {       public static byte[] encrypt(RSAPublicKey publicKey,byte[] srcBytes) throws Exception{          if(publicKey!=null){              Cipher cipher = Cipher.getInstance("RSA");              cipher.init(Cipher.ENCRYPT_MODE, publicKey);              byte[] resultBytes = cipher.doFinal(srcBytes);              return resultBytes;          }          return null;      }      public static byte[] decrypt(RSAPrivateKey privateKey,byte[] srcBytes) throws Exception{          if(privateKey!=null){              Cipher cipher = Cipher.getInstance("RSA");              cipher.init(Cipher.DECRYPT_MODE, privateKey);              byte[] resultBytes = cipher.doFinal(srcBytes);              return resultBytes;          }          return null;      }      public static void main(String[] args) throws Exception {          String msg = "皇子讲java密码技术";          KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");          keyPairGen.initialize(1024);          KeyPair keyPair = keyPairGen.generateKeyPair();          RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();                       RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();          byte[] srcBytes = msg.getBytes();          byte[] resultBytes = RSA.encrypt(publicKey, srcBytes);          byte[] decBytes = RSA.decrypt(privateKey, resultBytes);          System.out.println("明文:" + msg);          System.out.println("密文:" + new String(resultBytes));          System.out.println("解密:" + new String(decBytes));      }  }

4,数字签名

数字签名(又称公钥数字签名、电子签章)是一种类似写在纸上的普通的物理签名,但是使用了公钥加密领域的技术实现,用于鉴别数字信息的方法。一套数字签名通常定义两种互补的运算,一个用于签名,另一个用于验证。
数字签名会使用公钥和私钥组成的密钥对
私钥加密相当于生成签名;用公钥解密相当于验证签名

package com.huangzi.demo;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.PrivateKey;import java.security.PublicKey;import java.security.Signature;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.PKCS8EncodedKeySpec;public class RSASign {    public static byte[] sign(PrivateKey rsaPrivateKey,String msg) throws Exception{        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());        KeyFactory keyFactory = KeyFactory.getInstance("RSA");        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);        Signature signature = Signature.getInstance("MD5withRSA");        signature.initSign(privateKey);        signature.update(msg.getBytes());        return signature.sign();    }    public static boolean verify(PublicKey rsaPublicKey,String msg,byte[] signatureByte) throws Exception {        Signature signature = Signature.getInstance("MD5withRSA");        signature = Signature.getInstance("MD5withRSA");        signature.initVerify(rsaPublicKey);        signature.update(msg.getBytes());        return signature.verify(signatureByte);    }    public static void main(String[] args) throws Exception {        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");        keyPairGenerator.initialize(1024);        KeyPair keyPair = keyPairGenerator.generateKeyPair();        PublicKey rsaPublicKey = (RSAPublicKey)keyPair.getPublic();        PrivateKey rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate();        String msg = "皇子讲java密码技术";        byte[] signature = RSASign.sign(rsaPrivateKey, msg);        System.out.println("消息明文:" + msg);        System.out.println("签名:" + new String(signature));        boolean flag = RSASign.verify(rsaPublicKey, msg, signature);        System.out.println("验签结果:" + flag);    }}
作者:VIP.FCS 皇子                        日期:2018.1.14

转载地址:http://nuvcz.baihongyu.com/

你可能感兴趣的文章
MySQL中的GROUP_CONCAT()函数详解与实战应用
查看>>
MySQL主从篇:死磕主从复制中数据同步原理与优化
查看>>
Mysql事务。开启事务、脏读、不可重复读、幻读、隔离级别
查看>>
MySQL事务原理以及MVCC详解
查看>>
mysql事务理解
查看>>
Mysql全局优化参数
查看>>
MySQL函数简介
查看>>
mysql函数遍历json数组
查看>>
MySQL函数(转发)
查看>>
mysql分区表
查看>>
MySQL分层架构与运行机制详解
查看>>
mysql分库分表中间件简书_MySQL分库分表
查看>>
MySQL分库分表会带来哪些问题?分库分表问题
查看>>
MySQL分组函数
查看>>
MySQL分组查询
查看>>
Mysql分表后同结构不同名称表之间复制数据以及Update语句只更新日期加减不更改时间
查看>>
mysql创建函数报错_mysql在创建存储函数时报错
查看>>
mysql加强(4)~多表查询:笛卡尔积、消除笛卡尔积操作(等值、非等值连接),内连接(隐式连接、显示连接)、外连接、自连接
查看>>
mysql加强(5)~DML 增删改操作和 DQL 查询操作
查看>>
mysql加强(6)~子查询简单介绍、子查询分类
查看>>