Upload
norman-kemp
View
46
Download
6
Embed Size (px)
DESCRIPTION
RSA 中的密钥对生成. 通过前几天的学习 , 我们已经知道要生成 RSA 的密钥,需要做如下工作 : 确定两个大素数 p,q( 到少 512bit) 此处涉及到素数的判定(该算法是比较费时的). 计算 n=pq; 计算 选定一个 e, 使 最后得到公钥 : n,e 最后得到私钥 : d ( ). RSA 中的密钥对生成. KeyPairGenerator - PowerPoint PPT Presentation
Citation preview
RSA 中的密钥对生成通过前几天的学习 , 我们已经知道要生成 RSA 的密钥,需要做如下工作 :
确定两个大素数 p,q( 到少 512bit)此处涉及到素数的判定(该算法是比较费时的).
计算 n=pq; 计算 选定一个 e, 使
最后得到公钥 : n,e 最后得到私钥 : d ( )
gcd( , (n) )=1e
-1(mod ( ))d e n
( ) ( 1)( 1)n p q
KeyPairGenerator The KeyPairGenerator class is an engine class used to ge
nerate pairs of public and private keys
1. Creating the Key Pair Generator
try{// 取得 KeyPairGenerator 实例KeyPairGenerator keyGen=KeyPairGenerator.getInstance
("RSA");System.out.println("Key Test program is ok");
}catch(NoSuchAlgorithmException e){
System.out.println("Error: "+e.getMessage());}
RSA 中的密钥对生成
2. Initializing the Key Pair Generator
SecureRandom random = SecureRandom.getInstance(“SHA1PRNG”, “SUN”); random.setSeed(userSeed); // 这两条语句可省略 , 省略时系统采用 keyGen.initialize(1024, random); // 默认值
RSA 中的密钥对生成
The KeyPair Class
KeyPair 类是用于封装密钥对的类.KeyPair pair = keyGen.generateKeyPair();
RSA 中的密钥对生成
The PublicKey Class
封装了公钥体制中的公钥 (n,e)
RSA 中的密钥对生成
The PrivateKey Class
封装了公钥体制中的私钥 (n,d,p,q)
RSA 中的密钥对生成
因数字签名及验证要需要重复使用密钥对,因此需将密钥对存入文件中备用(存 10 进制数)。
KeyFactory
用于实验密钥对象与密钥的标准表达方式之间的转换.
// 通过 KeyFactory 类读取密钥的详细信息RSAPublicKeySpec;
RSAPrivateKeySpec;
RSA 中的密钥对的保不存
// 取得 KeyPairGenerator 实例KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
// 生成随机数对象SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
// 初始化 keyGen 为产生一对 1024 位的密钥的对象keyGen.initialize(1024, random);
// 生成密钥对KeyPair pair = keyGen.generateKeyPair();
// 读取公钥对象和私钥对象PublicKey puKey = pair.getPublic();PrivateKey prKey = pair.getPrivate();
// 将公钥和私钥输出System.out.println(puKey.toString());System.out.println(prKey.toString());
用于测试 RSA 密钥对的代码
Java 中公钥密码体制 API Sun RSA public key, 1024 bits modulus( n) : 145334580766753352968271624143227642903180026858070538178093842654655131896488508859021
170467602039725331815700222176862989556902870844823932940664684208523041952356061062674190324733884210594543025749003442008772730874286810845100551163211606567048423518752061867186661617099735966587084128589872797083364747
public exponent( e): 65537
Sun RSA private CRT( 中国剩余定理 ) key, 1024 bits modulus(n ): 14533458076675335296827162414322764290318002685807053817809384265465513189648850885
9021170467602039725331815700222176862989556902870844823932940664684208523041952356061062674190324733884210594543025749003442008772730874286810845100551163211606567048423518752061867186661617099735966587084128589872797083364747
public exponent( e ): 65537 private exponent( d ) : 12365092831489693162881818652978058410727398442985115489375977802738781908565089
5913303346874330868563479816159248796247973430327100346926738740536218117730278249237671789995775819474273027581511787552426991635086254315333676872987600640893099168403376116367516517690236495972293965947291133168132306425021585
prime p: 12836193223793558297927305428496631019420276059582307483685094836716895113592759865558860520415443996103674401559926195951777679843538568226126094329161913
prime q: 11322249379773806480799329481584580801659487779713145666093610874564424578061919183694263286905364957495175786438352752223906032465534494985244811289566819
• prime exponent p: 9148115978816938941686233038570458596274819322137278722560991875406808674040267864575090381418803770786186738386857391005381389023790468073571745545755305
• prime exponent q: 6844970668111417772796286576893398781490616984604338685571432266675573587551937073365433353532774844453001508071379135387084866751864476949057550209865067
• crt coefficient: 12215131375839181768650789125852251387959893277517099645583985397510200970338820228475780242328195082955827984916897355413623358654311131059893783646946460
用于保存公钥 ( 或私钥 ) 的代码// 通过 KeyFactory 类读取密钥的详细信息KeyFactory keyFactory;RSAPublicKeySpec rsaPublicKeySpec;RSAPrivateKeySpec rsaPrivateKeySpec;
// 读取 KeyFactory 实例keyFactory = KeyFactory.getInstance("RSA");
// 取得 KeySpec 对象rsaPublicKeySpec =(RSAPublicKeySpec)keyFactory.getKeySpec
(puKey,RSAPublicKeySpec.class);rsaPrivateKeySpec =(RSAPrivateKeySpec)keyFactory.getKeySpec
(prKey,RSAPrivateKeySpec.class);
// 读取 RSA 体制中的 n,e,dBigInteger n=rsaPublicKeySpec.getModulus();BigInteger e=rsaPublicKeySpec.getPublicExponent();BigInteger d=rsaPrivateKeySpec.getPrivateExponent();
byte[] array_n=n.toByteArray();byte[] array_e=e.toByteArray();byte[] array_d=d.toByteArray();
用于保存公钥 ( 或私钥 ) 的代码
FileOutputStream os=new FileOutputStream("keypair.dat");BufferedOutputStream bos=new BufferedOutputStream(os);
bos.write(array_n.length);bos.write(array_n);
bos.write(array_e.length);bos.write(array_e);
bos.write(array_d.length);bos.write(array_d);bos.close();
用于保存公钥 ( 或私钥 ) 的代码
// 测试读取密钥对FileInputStream is=new FileInputStream("keypair.dat");BufferedInputStream bis=new BufferedInputStream(is);int rn=bis.read();byte[] arr_n=new byte[rn];bis.read(arr_n);rn=bis.read();byte[] arr_e=new byte[rn];bis.read(arr_e);
rn=bis.read();byte[] arr_d=new byte[rn];bis.read(arr_d);
BigInteger bnd=new BigInteger(arr_d);依此类推,其它几个大整数也可生成。
RSA 中的密钥对的读取代码
package digitalSignature;
import java.security.*;import java.security.spec.*;import java.math.*;
public class TestKeyFactory {
/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stubKeyFactory keyFactory;RSAPublicKeySpec rsaPublicKeySpec;RSAPrivateKeySpec rsaPrivateKeySpec;
PublicKey puKey;PrivateKey prKey;
BigInteger modulus;BigInteger publicExponent;BigInteger privateExponent;
try {// 读取 KeyFactory 实例keyFactory = KeyFactory.getInstance("RSA");
// 生成大素数 n 对象 (bigInteger)
modulus = new BigInteger("9908842694202035033804057516779935421552198593080972892707221058927654490879870406722707400314348221540548472370090181823987070038991183751998319866577082
6399629190926127255679465937072030430667011751449223370297974871901357097820367416435228232213549910308078793020749883422710315131220984840513736926929187");
// 生成公钥指数 epublicExponent = new BigInteger("65537");// 生成私钥 dprivateExponent = new BigInteger("3588907014850751569302942052211809010198583060011337924442548579821562394525466283845414125780271964458367015405783460426262738323626863126496240576665702
7829284982577266629738492444164319964326342566063539272771497026747971277605799490434921044951013674084477470337244317547033260901498781303801882308400609");
// 生 RSAPublicKeySpec 对象rsaPublicKeySpec = new RSAPublicKeySpec(modulus, publicExponent);
// 生 RSAPrivateKeySpec 对象rsaPrivateKeySpec = new RSAPrivateKeySpec(modulus, privateExpone
nt);
// 生成 PublicKey 对象puKey = keyFactory.generatePublic(rsaPublicKeySpec);
// 生成 PrivateKey 对象prKey = keyFactory.generatePrivate(rsaPrivateKeySpec);
System.out.println(puKey.toString());
System.out.println(prKey.toString());
System.out.println(keyFactory.getProvider().getName());
System.out.println("bit count :" + modulus.bitCount());
System.out.println("bit length: " + modulus.bitLength());
} catch (NoSuchAlgorithmException e) {System.out.println(e.getMessage());
}
catch (InvalidKeySpecException e) {
System.out.println(e.getMessage());}}
}
SHA 数字摘要的计算import java.io.*;import java.security.*;
import tool.Tools;
public class TestSHA {
public static void main(String[] args) {try {
byte[] a = new byte[512];int len;// 打开相应的文件 ?FileInputStream in = new FileInputStream("GEF-ALL-3.2M3.zip");BufferedInputStream read = new BufferedInputStream(in);
// 构造 MessageDigest 对象MessageDigest sha = MessageDigest.getInstance("SHA");
while ((len = read.read(a, 0, 512)) > 0) {sha.update(a, 0, len);
}
byte[] hash = sha.digest();
System.out.println(" 计算出的摘要为 :" + sha.getDigestLength() * 8 + " bits");System.out.println(Tools.toHexString(hash));
// 关闭相应的文件in.close();
SHA 数字摘要的计算
System.out.println(sha.getAlgorithm());
} catch (FileNotFoundException e) {System.out.println(e.getMessage());
} catch (NoSuchAlgorithmException e) {System.out.println(e.getMessage());
} catch (IOException e) {System.out.println(e.getMessage());
}}
}
SHA 数字摘要的计算