java程序实现加密解密以及签名和签名验证

1 生成RSA密钥

生成非对称加密的公钥和私钥-生成RSA密钥

非对称加密将加密的密钥和解密的密钥分开。A事先生成一对密钥,一个用于加密,称为公钥(公钥),一个用于解密,称为私钥。由于产生这一对密钥的一些数学特性,公钥加密的信息只能用私钥解密。这样,A只要将公钥对外公开,不论谁就可以使用这个公钥给A发送秘密信息了。A接收到加密信息后可以用私钥打开。由于只需要传递公钥,而公钥只能加密不能解密,因此即使攻击者知道了公钥也无济于事。

本文介绍的是RSA非对称加密算法。

GenerateRSAKey.java

package sign;

import java.io.*;

import java.security.*;

public class GenerateRSAKey {

   public static void main(String args[]) throws Exception{

        KeyPairGenerator kpg=KeyPairGenerator.getInstance("RSA");

        kpg.initialize(1024);

        KeyPair kp=kpg.genKeyPair();

        PublicKey pbkey=kp.getPublic();

        PrivateKey prkey=kp.getPrivate();

        //  保存公钥        

        FileOutputStream  f1=new FileOutputStream("RSA_pub.dat");

        ObjectOutputStream b1=new  ObjectOutputStream(f1);

        b1.writeObject(pbkey);

        //  保存私钥

        FileOutputStream  f2=new FileOutputStream("RSA_priv.dat");

        ObjectOutputStream b2=new  ObjectOutputStream(f2);

        b2.writeObject(prkey);

}

}

2 对称密钥的生成和保存-生成DES密钥

对称密钥的生成及以对象序列化方式保存

import java.io.*;

import javax.crypto.*;

public class GetDesKey{

    public static void main(String args[]) throws Exception{  

        KeyGenerator kg=KeyGenerator.getInstance("DESede");

        kg.init(168); 

        SecretKey k=kg.generateKey( );

        FileOutputStream  f=new FileOutputStream("DesKey.dat");

        ObjectOutputStream b=new  ObjectOutputStream(f);

        b.writeObject(k);//要写入对象数据只能使用对象数据流

        byte[] c=k.getEncoded();//生成编码的字节表示展示一下,使用时可以删除

        for(int i=0;i<c.length;i++){

            System.out.print(c[i]);

        }}}


以字节保存对称密钥

import java.io.*;

import java.security.*;

public class Skey_kb{

    public static void main(String args[]) throws Exception{

        FileInputStream f=new FileInputStream("key1.dat");

        ObjectInputStream b=new ObjectInputStream(f);

        Key k=(Key)b.readObject( );

        byte[ ] kb=k.getEncoded( );

        FileOutputStream  f2=new FileOutputStream("keykb1.dat");

        f2.write(kb);

        // 打印密钥编码中的内容

        for(int i=0;i<kb.length;i++<span style="font-family: Verdana, Arial, Helvetica, sans-serif;"> ){</span>

            System.out.print(kb[i]+",");

        }

    }

}

3 使用CBC方式进行加密

对明文分组的不同处理方式形成了不同的加密方式,本章前面各节的程序中没有指定加密方式,默认的加密方式是ECB(Electronic Code Book),它对每个明文分组独立进行处理。所以明文若8个字节一组相同的话(如本节开头的“Hello123Hello123Hello123Hello123”),加密出的结果也是8个字节一组相同的。

另一种加密方式称为CBC(Cipher Block Chaining),它先加密第一个分组,然后使用得到的密文加密第二个分组,加密第二个分组得到的密文再加密第三个分组,……。这样,即使两个分组相同,得到的密文也不同。剩下的问题是如果两个密文的开头8个字节相同,按照这种加密方式,只要使用的密钥相同,则每条密文的开头8个字节也将相同。为此,CBC使用一个8个字节的随机数(称为初始向量,IV)来加密第一个分组,其作用类似于基于口令加密中的盐。

因此,使用CBC方式首先要生成初始向量,然后在获取密码器对象时通过getInstance( )方法的参数设定加密方式,在密码器初始化时传入初始向量。

//必须拥有DES加密密钥文件 DesKey.dat 和需要加密的文件1.txt

import java.io.*;

import java.util.*;

import java.security.*;

import javax.crypto.*;

import javax.crypto.spec.*;

public class CBC{

    public static void main(String args[]) throws Exception{

        FileInputStream fi=new FileInputStream("1.txt");

        int l=fi.available();

        byte[] c=new byte[l];

        fi.read(c);



        FileInputStream f1=new FileInputStream("DesKey.dat");

        ObjectInputStream b=new ObjectInputStream(f1);

        Key k=(Key)b.readObject( );

        byte[] rand=new byte[8];  

        Random r=new Random( );

        r.nextBytes(rand);

        IvParameterSpec iv=new IvParameterSpec(rand);

        Cipher cp=Cipher.getInstance("DESede/CBC/PKCS5Padding");

        cp.init(Cipher.ENCRYPT_MODE, k, iv);

        byte ptext[]=c;

        byte ctext[]=cp.doFinal(ptext);

        for(int i=0;i< div=""> 

             System.out.print(ctext[i] +",");

        }

        FileOutputStream f2=new FileOutputStream("SEncCBC.dat");

        f2.write(rand);

        f2.write(ctext);

        Cipher cp1=Cipher.getInstance("DESede/CBC/PKCS5Padding");

        cp1.init(Cipher.DECRYPT_MODE, k, iv);

        byte[] jm=cp1.doFinal(ctext);

        FileOutputStream fo=new FileOutputStream("2.txt");

        fo.write(jm);

        fo.close();

   }   

}



4 基于口令的加密解密

基于口令的加密和解密

import java.io.*;

import java.util.*;

import javax.crypto.*;

import javax.crypto.spec.*;

public class PBE{

   public static void main(String args[]) throws Exception{

  FileInputStream fi=new FileInputStream("1.rar");

  int l=fi.available();

  byte[] b=new byte[l];

  fi.read(b);

  //生成密钥

  char[] passwd="123".toCharArray();

       PBEKeySpec pbks=new PBEKeySpec(passwd);

       SecretKeyFactory kf=

       SecretKeyFactory.getInstance("PBEWithMD5AndDES"); 

       SecretKey k=kf.generateSecret(pbks);

       //生成盐

       byte[] salt=new byte[8];

       Random r=new Random( );

       r.nextBytes(salt);

       //创建并初始化密码器

       Cipher cp=Cipher.getInstance("PBEWithMD5AndDES");

       PBEParameterSpec ps=new PBEParameterSpec(salt,1000);

       cp.init(Cipher.ENCRYPT_MODE, k,ps);

       //获取明文并加密

       byte ctext[]=cp.doFinal(b);

       //生成输出文件

       //准备解密

       Cipher cp1=Cipher.getInstance("PBEWithMD5AndDES");

       cp1.init(Cipher.DECRYPT_MODE, k,ps);

       byte ptext1[]=cp1.doFinal(ctext);

       

       FileOutputStream f=new FileOutputStream("2.rar");

       f.write(ptext1);

       f.close();

   }

}



5 针对流的加密和解密

针对流的加密和解密

针对输入流的加密和解密

//必须拥有的文件:key1.dat(DES密钥文件),需要加密的文件1.rar

import java.io.*;
import java.security.*;
import java.util.Scanner;
import javax.crypto.*;
public class StreamInCipher{
    public static void main(String args[]) throws Exception{
        Scanner reader=new Scanner(System.in);
        System.out.println("please choose the type of opration:1.加密  2.解密");
        int choose=reader.nextInt();
        String fi="1.zip";
        String fc="code.txt";
        String fo="2.zip";
        String f1=null;
        String f2=null;
        if(choose==1){
            f1=fi;
            f2=fc;
        }
        if(choose==2){
            f1=fc;
            f2=fo;
        }
        FileInputStream f=new FileInputStream("key1.dat");
        ObjectInputStream ob=new ObjectInputStream(f);
        Key k=(Key)ob.readObject( );
        Cipher cp=Cipher.getInstance("DESede");
        if(choose==1)
            cp.init(Cipher.ENCRYPT_MODE, k);
        else
            cp.init(Cipher.DECRYPT_MODE, k);
        FileInputStream in=new FileInputStream(f1);
        FileOutputStream out=new FileOutputStream(f2);
        CipherInputStream cin=new CipherInputStream(in, cp);
        int b=0;
        while( (b=cin.read())!=-1){
            out.write(b);
            System.out.println("ok!");
            System.out.println(b);
        }
        cin.close();
        out.close();
        in.close();
   }
}


针对输出流的加密和解密

import java.io.*;
import java.security.*;
import java.util.Scanner;
import javax.crypto.*;
public class StreamOutCipher{
    public static void main(String args[]) throws Exception{
        Scanner reader=new Scanner(System.in);
        System.out.println("please choose the type of opration:1.加密  2.解密");
        int choose=reader.nextInt();
        String fi="1.zip";
        String fc="code.txt";
        String fo="2.zip";
        String f1=null;
        String f2=null;
        if(choose==1){
            f1=fi;
            f2=fc;
        }
        if(choose==2){
            f1=fc;
            f2=fo;
        }
        FileInputStream f=new FileInputStream("key1.dat");
        ObjectInputStream ob=new ObjectInputStream(f);
        Key k=(Key)ob.readObject( );
        Cipher cp=Cipher.getInstance("DESede");
        if(choose==1)
            cp.init(Cipher.ENCRYPT_MODE, k);
        else
            cp.init(Cipher.DECRYPT_MODE, k);
        FileInputStream in=new FileInputStream(f1);
        FileOutputStream out=new FileOutputStream(f2);
        CipherOutputStream cout=new CipherOutputStream(out, cp);
        int b=0;
        while( (b=in.read())!=-1){
            cout.write(b);
            //System.out.println(b);
        }
        cout.close();
        out.close();
        in.close();
   }
}

6 数字签名与数字签名验证

(对字符串或文件进行签名以及相应数字签名验证)
Sign.java
//对字符串或文件进行签名
package sign;

import java.io.*;

import java.security.*;

import java.security.interfaces.*;

public class Sign{ 

    public static void main(String args[ ]) throws Exception{

        //获取要签名的数据,放在data数组

        FileInputStream f=new FileInputStream("1.txt");

        int num=f.available();

        byte[ ] data=new byte[num];

        f.read(data);

        //获取私钥

        FileInputStream f2=new FileInputStream("RSA_priv.dat");

        ObjectInputStream b=new ObjectInputStream(f2);

        RSAPrivateKey prk=(RSAPrivateKey)b.readObject( );



        //获取Signature对象

        Signature s=Signature.getInstance("MD5WithRSA");

         //初始化

        s.initSign(prk);

         //传入要签名的数据

        s.update(data);

        System.out.println("");

         //签名

        byte[ ] signeddata=s.sign( );

        //保存签名

        FileOutputStream  f3=new FileOutputStream("Sign.dat");

        f3.write(signeddata); 

}

}
CheckSign.java
package sign;

import java.io.*;

import java.security.*;

import java.security.interfaces.*;

public class CheckSign{

// 从签名者那儿得到msg.dat和sign.dat和公钥RSA_pub.dat

// 修改msg.dat则数据无法通过验证,因此不怕网络传递过程中被修改,或signer不承认,因为只有signer才能针对msg.dat得到sign.dat,

// 如果checker将内容改为$300,则signer可要求其用签名验证,

// 1.验证完整性  checker担心是否网络传递时将内容修改过了,或者是否确实是signer发来的,不是别人乱传的,经检查签名,正确,于是放心,

// 2. 不可否认性。 signer不承认这个文件是自己发的,或说checker改过内容了,checker展示其签名sign.dat,只有signer有私钥,能根据msg.dat生成这样的内容,别人都不能。   

public static void main(String args[ ]) throws Exception{

//获取数据,放在data数组

        FileInputStream f=new FileInputStream("1.txt");

        int num=f.available();

        byte[ ] data=new byte[num];

        f.read(data);

        //读签名

        FileInputStream f2=new FileInputStream("Sign.dat");

        int num2=f2.available();

        byte[ ] signeddata=new byte[num2];

        f2.read(signeddata);

        //读公钥

        FileInputStream f3=new FileInputStream("RSA_pub.dat");

        ObjectInputStream b=new ObjectInputStream(f3);

        RSAPublicKey  pbk=(RSAPublicKey)b.readObject( );

        //获取对象

        Signature s=Signature.getInstance("MD5WithRSA");

        //初始化

        s.initVerify(pbk);

        //传入原始数据

        s.update(data);

        boolean ok=false;

        try{

        //用签名验证原始数据

            ok=  s.verify(signeddata);

            System.out.println(ok);

        }

        catch(SignatureException e){ System.out.println(e);}   

        System.out.println("Check Over");

}

}  


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值