java安全之加密(对称与非对称)

一些基本的安全知识

对称加密与非对称加密

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

ü  非对称加密称为公钥加密,速度慢,加密和解密的钥匙不相同,某一个人持有私钥,任何人都可以知道公钥

问题:想让任何陌生人都可以与你进行加密数据的交换,且加密速度要快,如何实现呢?

数字摘要与MD5/SHA算法

ü  作用:数据的完整性校验

数字签名

ü  功能:必须能够验证内容没有修改,必须能够验证内容确实是被发送方签署

ü  方案:发送方的公钥可以验证发送方签名的真实性,数字摘要可以验证内容没有修改

数字证书

ü  问题:如何确认对方提供的公钥的真实性。

ü  方案:每个人或机构的公钥和私钥由一些权威的机构产生!

 

 

非对称加密,好比我研制的毒药,谁都可以购买我的毒药去放毒,但解药只有我自己才有。

md5算法可用于对一段信息进行不可逆的变换运算,产生一个128比特位的数字摘要。如果对输入信息作了任何形式的改变,对改变后的信息再次进行MD5运算所产生的数字摘要,与改变前的内容所运算出的MD5数字摘要都是不同的。MD5不是加密,因为结果是不能恢复出原始数据的。

你给我一个公钥,说是张孝祥的公钥,我怎么能相信你呢?我上你的网站,你说你是中国工商银行,并出示你的公钥,然后就想与我进行机密数据的传送,我能相信吗?这就需要每个人的公钥和私钥由一些权威可以信赖的机构产生!

 

 

密钥加密

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

l  基本步骤:

•    得到keyGenerator的实例对象,并调用其generateKey()方法创建SecretKey对象。

•    得到Cipher的实例对象,并调用其init()方法指定SecretKey对象和指定要进行加密、还是进行解密操作。

•    调用Cipher对象的doFinal()方法完成加密或解密操作。

l  扩展步骤:

•    把密钥保存为密钥文件并传递给对方,用密钥文件对其他文件加密后,再把加密的结果文件传递给对方,让对方用密钥文件解密。

•    单独使用CipherInputStream或CipherOutputStream都可以完成加密和解密操作,关键在于传入的Cipher对象的操作模式。

•    由于加密时所涉及的secretkey不好记忆和交换,可以使用SecretKeyFactory将口令生成SecretKey。

 

KeyGenerator.getInstance()其参数是一个算法名,看参数的帮助文档的超链接,再找到Standard Names document. 这个超链接所在页面,就知道有哪些算法了。

代码1:

                   KeyGeneratorkeyGenerator = KeyGenerator.getInstance("DES");

                   SecretKeykey = keyGenerator.generateKey();

                  

                   Ciphercipher = Cipher.getInstance("DES");

                   cipher.init(Cipher.ENCRYPT_MODE,key);

                  

                   byte[]source = new byte[]{1,2,3,4};

                   //***cipher.update()实验的结果有问题,这个方法对最终的加密和解密没有任何影响,可能是底层实现类对这个方法采用了空实现***/

                   byte[]dest = cipher.doFinal(source);

                   for(inti=0;i<dest.length;i++){

                            System.out.println(dest[i]+ ",");

                   }

                   System.out.println("------------");

                  

                   cipher.init(Cipher.DECRYPT_MODE,key);

                   byte[]source2 = cipher.doFinal(dest);

                   for(inti=0;i<source2.length;i++){

                            System.out.println(source2[i]+ ",");

                   }

代码2:如果要做试验,可以先讲解如何将密钥传递给对方,对方如何恢复密钥,然后再让学生用这个密钥解密我的数据

         privatestatic void secretDecrypt() throws Exception {

                   FileInputStreamfisKey = new FileInputStream("key.key");

                   ObjectInputStreamois = new ObjectInputStream(fisKey);

                   SecretKeysecretKey = (SecretKey)ois.readObject();

                   ois.close();

                   fisKey.close();

                  

                   Ciphercipher = Cipher.getInstance("AES");

                   cipher.init(Cipher.DECRYPT_MODE,secretKey);

                   FileInputStreamfis = new FileInputStream("dest.txt");

                   CipherInputStreamcis = new CipherInputStream(fis,cipher);

                   FileOutputStreamfos = new FileOutputStream("src2.txt");

                   intb = 0;

                   while((b=cis.read())!=-1){

                            fos.write(b);

                   }

                   fos.close();

                   cis.close();

                   fis.close();

        

                  

         }

        

         privatestatic void secretEncrypt() throws Exception {

                   KeyGeneratorkeyGenerator = KeyGenerator.getInstance("AES");

                   SecretKeysecretKey = keyGenerator.generateKey();

                   FileOutputStreamfosKey = new FileOutputStream("key.key");

                   ObjectOutputStreamobs = new ObjectOutputStream(fosKey);

                   obs.writeObject(secretKey);

                   obs.close();

                   fosKey.close();

                  

                   Ciphercipher = Cipher.getInstance("AES");

                   cipher.init(Cipher.ENCRYPT_MODE,secretKey);

                   FileInputStreamfis = new FileInputStream("src.txt");

                   CipherInputStreamcis = new CipherInputStream(fis,cipher);

                   FileOutputStreamfos = new FileOutputStream("dest.txt");

                   intb = 0;

                   while((b=cis.read())!=-1){

                            fos.write(b);

                   }

                   fos.close();

                   cis.close();

                   fis.close();

         }

代码3:基于口令的加密与解密

         1.Cipher.getInstance()方法中指定的参数必须与SecretKeyFactory.getInstance()方法中指定的参数相同。

         2.在Cipher.init()方法中必须设置PBEParameterSpec参数,且“盐”的长度必须固定为8个字节。

         privatestatic void pwdSecretDecrypt() throws Exception {

                   SecretKeyFactorykeyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");

                   KeySpeckeySpec = new PBEKeySpec("itcastzxx".toCharArray());

                   SecretKeysecretKey = keyFactory.generateSecret(keySpec);

                  

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

                   Ciphercipher = Cipher.getInstance("PBEWithMD5AndDES");

                   cipher.init(Cipher.DECRYPT_MODE,secretKey,parameterSpec);

                  

                  

                   FileInputStreamfis = new FileInputStream("dest.txt");

                   CipherInputStreamcis = new CipherInputStream(fis,cipher);

                   FileOutputStreamfos = new FileOutputStream("src2.txt");

                   intb = 0;

                   while((b=cis.read())!=-1){

                            fos.write(b);

                   }

                   fos.close();

                   cis.close();

                   fis.close();

        

                  

         }

        

         privatestatic void pwdSecretEncrypt() throws Exception {

                   SecretKeyFactorykeyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");

                   KeySpeckeySpec = new PBEKeySpec("itcastzxx".toCharArray());

                   SecretKeysecretKey = keyFactory.generateSecret(keySpec);

                  

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

                   Ciphercipher = Cipher.getInstance("PBEWithMD5AndDES");

                   cipher.init(Cipher.ENCRYPT_MODE,secretKey,parameterSpec);

                  

                   FileInputStreamfis = new FileInputStream("src.txt");

                   CipherInputStreamcis = new CipherInputStream(fis,cipher);

                   FileOutputStreamfos = new FileOutputStream("dest.txt");

                   intb = 0;

                   while((b=cis.read())!=-1){

                            fos.write(b);

                   }

                   fos.close();

                   cis.close();

                   fis.close();

         }

 

 

公钥加密

 

l  公钥加密也称为非对称加密、速度慢、加密和解密的钥匙不相同,某一个人持有私钥,任何人都可以知道公钥。

l  基本步骤:

•    得到keyPairGenerator的实例对象,并调用其generateKeyPair()方法创建KeyPair对象。

•    调用KeyPair对象的getPrivate和getPublic方法,分别得到PrivateKey对象和PublicKey对象。

•    得到Cipher的实例对象,并调用其init()方法指定PrivateKey对象或PublicKey对象,并指定要进行加密、还是进行解密操作。

•    调用Cipher对象的doFinal()方法完成加密或解密操作。

l  扩展步骤:

•    把公钥和私钥分别保存为公钥文件和私钥文件,把公钥文件传递给对方,对方用公钥文件对其他文件加密后,再把加密的结果文件传递回来,这边再用私钥文件解密。

•    单独使用CipherInputStream或CipherOutputStream都可以完成加密和解密操作,关键在于传入的Cipher对象的操作模式。

 

为什么要有公钥加密呢?假如我想与一万个人加密对话,如果用密钥方式,我要制造出一万对密钥,否则,如果只有一对密钥来与这一万个对话,在这一万个人彼此之间就没有机密性可言了。

代码1:

                   KeyPairGeneratorkeyGenerator = KeyPairGenerator.getInstance("RSA");

                   KeyPairkeyPair = keyGenerator.generateKeyPair();

                   PrivateKeyprivateKey = keyPair.getPrivate();

                   PublicKeypublicKey = keyPair.getPublic();

                  

                   Ciphercipher = Cipher.getInstance("RSA");

                   cipher.init(Cipher.ENCRYPT_MODE,publicKey);

                  

                  byte[] source = new byte[]{1,2,3,4};

                   byte[]dest = cipher.doFinal(source);

                   for(inti=0;i<dest.length;i++){

                            System.out.println(dest[i]+ ",");

                   }

                   System.out.println("------------");

                   cipher.init(Cipher.DECRYPT_MODE,privateKey);

                   byte[]source2 = cipher.doFinal(dest);

                   for(inti=0;i<source2.length;i++){

                            System.out.println(source2[i]+ ",");

                   }                

       在这里可以顺带演示一下:“代码改成私钥加密,用公钥解密”。

代码2:

       //公钥加密

         privatestatic void publicEncrypt() throws Exception{

                   {

                            KeyPairGeneratorkeyGenerator = KeyPairGenerator.getInstance("RSA");

                            KeyPairkeyPair = keyGenerator.generateKeyPair();

                            PrivateKeyprivateKey = keyPair.getPrivate();

                            PublicKeypublicKey = keyPair.getPublic();

                            FileOutputStreamfosPrivateKey = new FileOutputStream("private.key");

                            FileOutputStreamfosPublicKey = new FileOutputStream("public.key");

                           

                            ObjectOutputStreamoosPrivateKey = new ObjectOutputStream(fosPrivateKey);

                            ObjectOutputStreamoosPublicKey = new ObjectOutputStream(fosPublicKey);

                            oosPrivateKey.writeObject(privateKey);

                            oosPublicKey.writeObject(publicKey);

                           

                            oosPrivateKey.close();

                            oosPublicKey.close();

                            fosPrivateKey.close();

                            fosPublicKey.close();

                   }

                   FileInputStreamfisPublicKey = new FileInputStream("public.key");

                   ObjectInputStreamoisPublicKey = new ObjectInputStream(fisPublicKey);

                   PublicKeypublicKey = (PublicKey)oisPublicKey.readObject();

                   oisPublicKey.close();

                   fisPublicKey.close();

                  

                   Ciphercipher = Cipher.getInstance("RSA");

                   cipher.init(Cipher.ENCRYPT_MODE,publicKey);

                                    

                   FileInputStreamfis = new FileInputStream("src.txt");

                   FileOutputStreamfos = new FileOutputStream("dest.txt");

                   CipherOutputStreamcos = new CipherOutputStream(fos,cipher);

                   intlen = 0;

                   bytebuf[] = new byte[1024];

                   while((len=fis.read(buf))!= -1){

                            cos.write(buf,0,len);

                   }

                   cos.close();

                   fos.close();

                   fis.close();

                  

         }

          

         //私钥解密

         privatestatic void privateDecrypt() throws Exception{

                   FileInputStreamfisPrivateKey = new FileInputStream("private.key");

                   ObjectInputStreamoisPrivateKey = new ObjectInputStream(fisPrivateKey);

                   PrivateKeyprivateKey = (PrivateKey)oisPrivateKey.readObject();

                   oisPrivateKey.close();

                   fisPrivateKey.close();

                  

                   Ciphercipher = Cipher.getInstance("RSA");

                   cipher.init(Cipher.DECRYPT_MODE,privateKey);

                                    

                   FileInputStreamfis = new FileInputStream("dest.txt");

                   FileOutputStreamfos = new FileOutputStream("src2.txt");

                   CipherOutputStreamcos = new CipherOutputStream(fos,cipher);

                   intlen = 0;

                   bytebuf[] = new byte[1024];

                   while((len=fis.read(buf))!= -1){

                            cos.write(buf,0,len);

                   }

                   cos.close();

                   fos.close();

                   fis.close();                 

         }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值