Java安全之对称加密、非对称加密、数字签名

原文地址: http://blog.csdn.net/furongkang/article/details/6882039

Java中加密分为两种方式一个是对称加密,另一个是非对称加密。对称加密是因为加密和解密的钥匙相同,而非对称加密是加密和解密的钥匙不同。

 

对称加密与非对称加密的区别:

对称加密称为密钥加密,速度快,但加密和解密的钥匙必须相同,只有通信双方才能知道密钥。

非对称加密称为公钥加密,算法更加复杂,速度慢,加密和解密钥匙不相同,任何人都可以知道公钥,只有一个人持有私钥可以解密。

 

对称加密解密:

 1     /*

 2      * 对称加密

 3      */

 4     private static void secretEncrypt() throws Exception {

 5         //使用Cipher的实例

 6         Cipher cipher =Cipher.getInstance("AES");

 7         

 8         //得到加密的钥匙

 9         SecretKey key =KeyGenerator.getInstance("AES").generateKey();

10         

11         //初始化加密操作,传递加密的钥匙

12         cipher.init(Cipher.ENCRYPT_MODE,key);

13         

14         //将加密的钥匙写入secretKey.key文件中

15         FileOutputStream fosKey=new FileOutputStream("secretKey.key");

16         ObjectOutputStream oosSecretKey =new ObjectOutputStream(fosKey);

17         oosSecretKey.writeObject(key);

18         oosSecretKey.close();

19         fosKey.close();

20          

21          //将加密的内容传递进去,返回加密后的二进制数据

22         byte [] results =cipher.doFinal("哈哈哈哈哈".getBytes());

23         

24         //将加密后的二进制数据写入到secretContent.dat文件中

25         FileOutputStream fosData=new FileOutputStream("secretContent.dat");

26         fosData.write(results);

27         fosData.close();

28     }

29     

30     /*

31      * 对称解密

32      */

33     private static void secretDecrypt() throws Exception{

34         Cipher cipher =Cipher.getInstance("AES");

35         

36         //获取文件中的key进行解密

37         FileInputStream fisKey=new FileInputStream("secretKey.key");

38         ObjectInputStream oisKey =new ObjectInputStream(fisKey);

39         Key key =(Key)oisKey.readObject();

40         oisKey.close();

41         fisKey.close();

42         

43         //初始化解密操作,传递加密的钥匙

44         cipher.init(Cipher.DECRYPT_MODE,key);

45         

46         //获取文件中的二进制数据

47         FileInputStream fisDat=new FileInputStream("secretContent.dat");

48         //获取数据第一种方式

49         byte [] src=new byte [fisDat.available()];

50         int len =fisDat.read(src);

51         int total =0;

52         while(total<src.length){

53             total +=len;

54             len=fisDat.read(src,total,src.length-total);

55         }

56         //执行解密

57         byte [] result=cipher.doFinal(src);

58         fisDat.close();

59         System.out.println(new String(result));

60         

61 //        读文件中的数据第二种方式

62 //        ByteArrayOutputStream baos =new ByteArrayOutputStream();

63 //        copyStream(fisDat, baos);

64 //        byte [] result=cipher.doFinal(baos.toByteArray());

65 //        fisDat.close();

66 //        baos.close();

67     }

68     

69 //    private static void copyStream(InputStream ips,OutputStream ops) throws Exception{

70 //        byte [] buf =new byte[1024];

71 //        int len=ips.read(buf);

72 //        while(len!=-1){

73 //            ops.write(buf,0,len);

74 //            len  =ips.read(buf);

75 //        }

76 //    }

 

基于口令的对称加密与解密 

系统自动生成的Key不容易记忆,我们可以使用我们容易记忆的口令同过java自带的一个工具将它转换成Key,在解密的时候我们就可以通过口令进行解密。

 1     /*

 2      * 基于口令的对称加密

 3      */

 4     private static void secretEncrypt() throws Exception {

 5         //实例化工具

 6         Cipher cipher2=Cipher.getInstance("PBEWithMD5AndDES");

 7         

 8         //使用该工具将基于密码的形式生成Key

 9         SecretKey key2=SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(new PBEKeySpec("123".toCharArray()));

10         PBEParameterSpec parameterspec=new PBEParameterSpec(new byte[]{1,2,3,4,5,6,7,8},1000);

11         

12         //初始化加密操作,同时传递加密的算法

13         cipher2.init(Cipher.ENCRYPT_MODE,key2,parameterspec);

14         

15          //将要加密的数据传递进去,返回加密后的数据

16         byte [] results =cipher2.doFinal("哈哈哈哈哈".getBytes());

17         

18         //将加密后的数据写入到文件中

19         FileOutputStream fosData=new FileOutputStream("zxx.dat");

20         fosData.write(results);

21         fosData.close();

22     }

23     

24     /*

25      * 基于口令的对称解密

26      */

27     private static void secretDecrypt() throws Exception{

28         Cipher cipher2=Cipher.getInstance("PBEWithMD5AndDES");

29         SecretKey key2=SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(new PBEKeySpec("123".toCharArray()));

30         PBEParameterSpec parameterspec=new PBEParameterSpec(new byte[]{1,2,3,4,5,6,7,8},1000);

31         cipher2.init(Cipher.DECRYPT_MODE,key2,parameterspec);

32         FileInputStream fisDat=new FileInputStream("zxx.dat");

33         byte [] src=new byte [fisDat.available()];

34         int len =fisDat.read(src);

35         int total =0;

36         while(total<src.length){

37             total +=len;

38             len=fisDat.read(src,total,src.length-total);

39         }

40         byte [] result=cipher2.doFinal(src);

41         fisDat.close();

42         System.out.println(new String(result));

43     }

 

非对称加密解密: 

非对称加密是公钥加密,私钥来解密,这个个人做用的少一点,主要针对于大型的网站大型的企业

 1     /*

 2      * 公钥加密

 3      */

 4     private static void PublicEnrypt()throws Exception {

 5         Cipher cipher =Cipher.getInstance("RSA");

 6         //实例化Key

 7         KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA");

 8         //获取一对钥匙

 9         KeyPair keyPair=keyPairGenerator.generateKeyPair();

10         //获得公钥

11         Key publicKey=keyPair.getPublic();

12         //获得私钥 

13         Key privateKey=keyPair.getPrivate();

14         //用公钥加密

15         cipher.init(Cipher.ENCRYPT_MODE, publicKey);

16         byte [] result=cipher.doFinal("传智播客".getBytes("UTF-8"));

17         //将Key写入到文件

18         saveKey(privateKey,"zxx_private.key");

19         //加密后的数据写入到文件

20         saveData(result,"public_encryt.dat");

21     }

22     

23     /*

24      * 私钥解密

25      */

26     private static void privateDecrypt() throws Exception {

27         Cipher cipher=Cipher.getInstance("RSA");

28         //得到Key

29         Key privateKey=readKey("zxx_private.key");

30         //用私钥去解密

31         cipher.init(Cipher.DECRYPT_MODE, privateKey);

32         //读数据源

33         byte [] src =readData("public_encryt.dat");

34         //得到解密后的结果

35         byte[] result=cipher.doFinal(src);

36         //二进制数据要变成字符串需解码

37         System.out.println(new String(result,"UTF-8"));

38     }

39 

40     private static void saveData(byte[] result, String fileName) throws Exception {

41         // TODO Auto-generated method stub

42         FileOutputStream fosData=new FileOutputStream(fileName);

43         fosData.write(result);

44         fosData.close();

45     }

46     public static void saveKey(Key key,String fileName)throws Exception{

47         FileOutputStream fosKey=new FileOutputStream(fileName);

48         ObjectOutputStream oosSecretKey =new ObjectOutputStream(fosKey);

49         oosSecretKey.writeObject(key);

50         oosSecretKey.close();

51         fosKey.close();

52     }

53     private static Key readKey(String fileName) throws Exception {

54         FileInputStream fisKey=new FileInputStream(fileName);

55         ObjectInputStream oisKey =new ObjectInputStream(fisKey);

56         Key key=(Key)oisKey.readObject();

57         oisKey.close();

58         fisKey.close();

59         return key;

60     }

61     private static byte[] readData(String filename) throws Exception {

62         FileInputStream fisDat=new FileInputStream(filename);

63         byte [] src=new byte [fisDat.available()];

64         int len =fisDat.read(src);

65         int total =0;

66         while(total<src.length){

67             total +=len;

68             len=fisDat.read(src,total,src.length-total);

69         }

70         fisDat.close();

71         return src;

72     }

 

数字签名: 

数字签名的基础是公钥和私钥的非对称加密,发送者使用私钥加密的消息摘要(签名),接收者使用公钥解密消息摘要以验证签名是否是某个人。

要证明这段数据是你发过来的,并且没有被别人改过,这就需要用到数字签名,首先我们对整个文档进行md5加密得到16个字节,然后把消息摘要和文档发过去,解密者首先对发过来的文档进行解密,解密后得到一个摘要(md5),对接收的文档进行md5加密,得到的md5结果匹配解密后的摘要,如果匹配成功的话证明没有修改过,我们使用Signature进行签名

 1     /* 

 2      * 使用私钥签名 

 3      */  

 4     private static void sign()throws Exception {  

 5         //实例化Key   

 6         KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA");  

 7         //获取一对钥匙   

 8         KeyPair keyPair=keyPairGenerator.generateKeyPair();  

 9         //获得公钥   

10         PublicKey publicKey=keyPair.getPublic();  

11         //获得私钥    

12         PrivateKey privateKey=keyPair.getPrivate();  

13         

14         //数字签名

15         Signature signature =Signature.getInstance("SHA1withRSA");

16         signature.initSign(privateKey);//用私钥签名

17         signature.update("这里签名".getBytes());//对怎样的数据进行签名

18         byte [] sign=signature.sign();  //获取签名的结果

19         

20         //保存公钥并写入文件中 

21         saveKey(publicKey,"zxx_private.key");  

22         //将签名后的数据写入到文件   

23         saveData(sign,"public_encryt.dat");  

24     }

25       

26     /* 

27      * 公钥解密 

28      */  

29     private static void verify() throws Exception {  

30         Signature signture =Signature.getInstance("SHA1withRSA");

31         //获取到公钥

32         PublicKey publicKey=(PublicKey)readKey("zxx_private.key");

33         //初始化校验

34         signture.initVerify(publicKey);

35         //初始化签名对象

36         signture.update("这里签名".getBytes());

37         //读数据源   

38         byte [] sign =readData("public_encryt.dat");  

39         //返回匹配结果

40         boolean isYouSigned=signture.verify(sign);

41         //如果返回数据为true则数据没有发生修改,否则发生修改

42         System.out.println(isYouSigned);

43     } 

 

你可能感兴趣的:(java)