用RSA算法进行加密和解密
一、 生成公钥和私钥
公钥可以对外公开,供其他人加密使用,而把私钥秘密保存用于解密。下面程序产生公钥和私钥,并将他们分别保存在文件中。
import java.io.*; import java.security.*; import javax.crypto.*; import javax.crypto.spec.*; public class Skey_RSA{ public static void main(String args[]) throws Exception{ //创建密钥对生成器,指定加密和解密算法为RSA KeyPairGenerator kpg=KeyPairGenerator.getInstance("RSA"); //指定密钥的长度,初始化密钥对生成器 kpg.initialize(1024); //生成密钥对 KeyPair kp=kpg.genKeyPair(); //获取公钥 PublicKey pbkey=kp.getPublic(); //获取私钥 PrivateKey prkey=kp.getPrivate(); //保存公钥到文件 FileOutputStream f1=new FileOutputStream("Skey_RSA_pub.dat"); ObjectOutputStream b1=new ObjectOutputStream(f1); b1.writeObject(pbkey); //保存私钥到文件 FileOutputStream f2=new FileOutputStream("Skey_RSA_priv.dat"); ObjectOutputStream b2=new ObjectOutputStream(f2); b2.writeObject(prkey); }}
二、使用RSA算法,用公钥对明文加密
import java.security.*; import java.security.spec.*; import javax.crypto.*; import javax.crypto.spec.*; import javax.crypto.interfaces.*; import java.security.interfaces.*; import java.math.*; import java.io.*; public class Enc_RSA{ public static void main(String args[]) throws Exception{ //需要加密的明文字符串 String s="Hello World!"; //从文件中读取公钥 FileInputStream f=new FileInputStream("Skey_RSA_pub.dat"); ObjectInputStream b=new ObjectInputStream(f); RSAPublicKey pbk=(RSAPublicKey)b.readObject( ); //RSA算法是使用整数进行加密的,在RSA公钥中包含有两个整数信息:e和n。对于明文数字m,计算密文的公式是m的e次方再与n求模。 BigInteger e=pbk.getPublicExponent(); BigInteger n=pbk.getModulus(); System.out.println("e= "+e); System.out.println("n= "+n); //获取明文的大整数 byte ptext[]=s.getBytes("UTF8"); BigInteger m=new BigInteger(ptext); //加密明文 BigInteger c=m.modPow(e,n); //打印密文c System.out.println("c= "+c); //将密文以字符串形式保存在文件中 String cs=c.toString( ); BufferedWriter out= new BufferedWriter(new OutputStreamWriter( new FileOutputStream("Enc_RSA.dat"))); out.write(cs,0,cs.length( )); out.close( ); } } 运行结果: C:\java>java Enc_RSA e= 65537 n= 13405802078375219658602862966795918240406064464423931951911888365236988242463 33406825151412877079295194644119374029616583316891373732288186538465516523463338 00587304780823025797697373087120665466308717068337942675197170744407800699203571 700904520312857964222781057020371566890161797790968413791779126227980669 c= 47607898340767965145701968255755546566892745661227674225772563975813289594435 28414345875647978484338295878599291349642839959842123774575104652337796795510160 29860635595339439914429389478586533022360831125097334674213734766040265793820856 94641532612227941560162099100409874338485658721364756817554501714726488
三、使用RSA算法,用私钥对密文解密
import java.security.*; import java.security.spec.*; import javax.crypto.*; import javax.crypto.spec.*; import javax.crypto.interfaces.*; import java.security.interfaces.*; import java.math.*; import java.io.*; public class Dec_RSA{ public static void main(String args[]) throws Exception{ //读取密文 BufferedReader in= new BufferedReader(new InputStreamReader(new FileInputStream("Enc_RSA.dat"))); String ctext=in.readLine(); BigInteger c=new BigInteger(ctext); //获取私钥 FileInputStream f=new FileInputStream("Skey_RSA_priv.dat"); ObjectInputStream b=new ObjectInputStream(f); RSAPrivateKey prk=(RSAPrivateKey)b.readObject( ); //获取私钥的参数d,n BigInteger d=prk.getPrivateExponent(); BigInteger n=prk.getModulus(); System.out.println("d= "+d); System.out.println("n= "+n); //解密明文 BigInteger m=c.modPow(d,n); System.out.println("m= "+m); //计算明文对应的字符串并输出。 byte[] mt=m.toByteArray(); System.out.println("PlainText is "); for(int i=0;i<mt.length;i++){ System.out.print((char) mt[i]); } } } 运行结果: C:\java>java Dec_RSA d= 64430162177802259610093989308045506009782293742530938038256352858421144645179 07387915012771839150959006500216983259054143661663562540185437171153217183581928 20085372721431999404588971809332312650448511194624894811079224536652906125419899 15290971295079971714184656932298777888024850821287330626750486312295257 n= 13405802078375219658602862966795918240406064464423931951911888365236988242463 33406825151412877079295194644119374029616583316891373732288186538465516523463338 00587304780823025797697373087120665466308717068337942675197170744407800699203571 700904520312857964222781057020371566890161797790968413791779126227980669 m= 22405534230753928650781647905 PlainText is Hello World!