加密算法Word下载.docx
《加密算法Word下载.docx》由会员分享,可在线阅读,更多相关《加密算法Word下载.docx(25页珍藏版)》请在冰点文库上搜索。
解密密钥只有解密人自己知道。
它们分别称为公开密钥(Publickey)和秘密密钥(Privatekey)。
迄今为止的所有公钥密码体系中,RSA系统是最著名、最多使用的一种。
RSA公开密钥密码系统是由R.Rivest、A.Shamir和L.Adleman俊教授于1977年提出的。
RSA的取名就是来自于这三位发明者的姓的第一个字母
1.5.数字签名
所谓数字签名就是信息发送者用其私钥对从所传报文中提取出的特征数据(或称数字指纹)进行RSA算法操作,以保证发信人无法抵赖曾发过该信息(即不可抵赖性),同时也确保信息报文在经签名后末被篡改(即完整性)。
当信息接收者收到报文后,就可以用发送者的公钥对数字签名进行验证。
在数字签名中有重要作用的数字指纹是通过一类特殊的散列函数(HASH函数)生成的,对这些HASH函数的特殊要求是:
接受的输入报文数据没有长度限制;
对任何输入报文数据生成固定长度的摘要(数字指纹)输出
从报文能方便地算出摘要;
难以对指定的摘要生成一个报文,而由该报文反推算出该指定的摘要;
DSA
回页首
第2章在JAVA中的实现
2.1.相关
Diffie-Hellman密钥一致协议和DES程序需要JCE工具库的支持,可以到下载JCE,并进行安装。
简易安装把jce1.2.1\lib下的所有内容复制到%java_home%\lib\ext下,如果没有ext目录自行建立,再把jce1_2_1.jar和sunjce_provider.jar添加到CLASSPATH内,更详细说明请看相应用户手册
2.2.消息摘要MD5和SHA的使用
使用方法:
首先用生成一个MessageDigest类,确定计算方法
java.security.MessageDigestalga=java.security.MessageDigest.getInstance("
SHA-1"
);
添加要进行计算摘要的信息
alga.update(myinfo.getBytes());
计算出摘要
byte[]digesta=alga.digest();
发送给其他人你的信息和摘要
其他人用相同的方法初始化,添加信息,最后进行比较摘要是否相同
algb.isEqual(digesta,algb.digest())
相关AIP
java.security.MessageDigest类
staticgetInstance(Stringalgorithm)
返回一个MessageDigest对象,它实现指定的算法
参数:
算法名,如SHA-1或MD5
voidupdate(byteinput)
voidupdate(byte[]input)
voidupdate(byte[]input,intoffset,intlen)
byte[]digest()
完成计算,返回计算得到的摘要(对于MD5是16位,SHA是20位)
voidreset()
复位
staticbooleanisEqual(byte[]digesta,byte[]digestb)
比效两个摘要是否相同
代码:
importjava.security.*;
publicclassmyDigest{
publicstaticvoidmain(String[]args){
myDigestmy=newmyDigest();
my.testDigest();
}
publicvoidtestDigest()
{
try{
Stringmyinfo="
我的测试信息"
;
//java.security.MessageDigestalg=java.security.MessageDigest.getInstance("
MD5"
java.security.MessageDigestalga=java.security.MessageDigest.getInstance("
alga.update(myinfo.getBytes());
byte[]digesta=alga.digest();
System.out.println("
本信息摘要是:
"
+byte2hex(digesta));
//通过某中方式传给其他人你的信息(myinfo)和摘要(digesta)对方可以判断是否更改或传输正常
java.security.MessageDigestalgb=java.security.MessageDigest.getInstance("
algb.update(myinfo.getBytes());
if(algb.isEqual(digesta,algb.digest())){
信息检查正常"
else
摘要不相同"
catch(java.security.NoSuchAlgorithmExceptionex){
非法摘要算法"
publicStringbyte2hex(byte[]b)//二行制转字符串
Stringhs="
Stringstmp="
for(intn=0;
n<
b.length;
n++)
stmp=(java.lang.Integer.toHexString(b[n]&
0XFF));
if(stmp.length()==1)hs=hs+"
0"
+stmp;
elsehs=hs+stmp;
if(n<
b.length-1)hs=hs+"
:
returnhs.toUpperCase();
}
2.3.数字签名DSA
对于一个用户来讲首先要生成他的密钥对,并且分别保存
生成一个KeyPairGenerator实例
java.security.KeyPairGeneratorkeygen=java.security.KeyPairGenerator.getInstance("
DSA"
//如果设定随机产生器就用如相代码初始化
SecureRandomsecrand=newSecureRandom();
secrand.setSeed("
tttt"
.getBytes());
//初始化随机产生器
keygen.initialize(512,secrand);
//初始化密钥生成器
//否则
keygen.initialize(512);
//生成密钥公钥pubkey和私钥prikey
KeyPairkeys=keygen.generateKeyPair();
//生成密钥组
PublicKeypubkey=keys.getPublic();
PrivateKeyprikey=keys.getPrivate();
//分别保存在myprikey.dat和mypubkey.dat中,以便下次不在生成
//(生成密钥对的时间比较长
java.io.ObjectOutputStreamout=newjava.io.ObjectOutputStream(
newjava.io.FileOutputStream("
myprikey.dat"
));
out.writeObject(prikey);
out.close();
out=newjava.io.ObjectOutputStream(newjava.io.FileOutputStream("
mypubkey.dat"
out.writeObject(pubkey);
用他私人密钥(prikey)对他所确认的信息(info)进行数字签名产生一个签名数组
从文件中读入私人密钥(prikey)
java.io.ObjectInputStreamin=newjava.io.ObjectInputStream(
newjava.io.FileInputStream("
PrivateKeymyprikey=(PrivateKey)in.readObject();
in.close();
初始一个Signature对象,并用私钥对信息签名
java.security.Signaturesignet=java.security.Signature.getInstance("
signet.initSign(myprikey);
signet.update(myinfo.getBytes());
byte[]signed=signet.sign();
把信息和签名保存在一个文件中(myinfo.dat)
myinfo.dat"
out.writeObject(myinfo);
out.writeObject(signed);
把他的公钥的信息及签名发给其它用户
其他用户用他的公共密钥(pubkey)和签名(signed)和信息(info)进行验证是否由他签名的信息
读入公钥java.io.ObjectInputStreamin=newjava.io.ObjectInputStream(newjava.io.FileInputStream("
PublicKeypubkey=(PublicKey)in.readObject();
in.close();
读入签名和信息in=newjava.io.ObjectInputStream(newjava.io.FileInputStream("
Stringinfo=(String)in.readObject();
byte[]signed=(byte[])in.readObject();
初始一个Signature对象,并用公钥和签名进行验证java.security.Signaturesignetcheck=java.security.Signature.getInstance("
signetcheck.initVerify(pubkey);
signetcheck.update(info.getBytes());
if(signetcheck.verify(signed)){System.out.println("
签名正常"
}
对于密钥的保存本文是用对象流的方式保存和传送的,也可可以用编码的方式保存.注意要importjava.security.spec.*importjava.security.*
具休说明如下
publickey是用X.509编码的,例码如下:
byte[]bobEncodedPubKey=mypublic.getEncoded();
//生成编码
//传送二进制编码
//以下代码转换编码为相应key对象
X509EncodedKeySpecbobPubKeySpec=newX509EncodedKeySpec(bobEncodedPubKey);
KeyFactorykeyFactory=KeyFactory.getInstance("
PublicKeybobPubKey=keyFactory.generatePublic(bobPubKeySpec);
对于Privatekey是用PKCS#8编码,例码如下:
byte[]bPKCS=myprikey.getEncoded();
PKCS8EncodedKeySpecpriPKCS8=newPKCS8EncodedKeySpec(bPKCS);
KeyFactorykeyf=KeyFactory.getInstance("
PrivateKeyotherprikey=keyf.generatePrivate(priPKCS8);
常用API
java.security.KeyPairGenerator密钥生成器类publicstaticKeyPairGeneratorgetInstance(Stringalgorithm)throwsNoSuchAlgorithmException以指定的算法返回一个KeyPairGenerator对象参数:
algorithm算法名.如:
"
RSA"
publicvoidinitialize(intkeysize)
以指定的长度初始化KeyPairGenerator对象,如果没有初始化系统以1024长度默认设置
keysize算法位长.其范围必须在512到1024之间,且必须为64的倍数
publicvoidinitialize(intkeysize,SecureRandomrandom)以指定的长度初始化和随机发生器初始化KeyPairGenerator对象参数:
keysize算法位长.其范围必须在512到1024之间,且必须为64的倍数random一个随机位的来源(对于initialize(intkeysize)使用了默认随机器
publicabstractKeyPairgenerateKeyPair()产生新密钥对
java.security.KeyPair密钥对类publicPrivateKeygetPrivate()返回私钥
publicPublicKeygetPublic()返回公钥
java.security.Signature签名类publicstaticSignaturegetInstance(Stringalgorithm)throwsNoSuchAlgorithmException返回一个指定算法的Signature对象参数algorithm如:
publicfinalvoidinitSign(PrivateKeyprivateKey)throwsInvalidKeyException用指定的私钥初始化参数:
privateKey所进行签名时用的私钥
publicfinalvoidupdate(bytedata)throwsSignatureExceptionpublicfinalvoidupdate(byte[]data)throwsSignatureExceptionpublicfinalvoidupdate(byte[]data,intoff,intlen)throwsSignatureException添加要签名的信息
publicfinalbyte[]sign()throwsSignatureException返回签名的数组,前提是initSign和update
publicfinalvoidinitVerify(PublicKeypublicKey)throwsInvalidKeyException用指定的公钥初始化参数:
publicKey验证时用的公钥
publicfinalbooleanverify(byte[]signature)throwsSignatureException验证签名是否有效,前提是已经initVerify初始化参数:
signature签名数组
importjava.security.*;
importjava.security.spec.*;
publicclasstestdsa{
publicstaticvoidmain(String[]args)throwsjava.security.NoSuchAlgorithmException,
java.lang.Exception{
testdsamy=newtestdsa();
my.run();
publicvoidrun()
//数字签名生成密钥
//第一步生成密钥对,如果已经生成过,本过程就可以跳过,
//对用户来讲myprikey.dat要保存在本地
//而mypubkey.dat给发布给其它用户
if((newjava.io.File("
)).exists()==false){
if(generatekey()==false){
生成密钥对败"
return;
};
//第二步,此用户
//从文件中读入私钥,对一个字符串进行签名后保存在一个文件(myinfo.dat)中
//并且再把myinfo.dat发送出去
//为了方便数字签名也放进了myifno.dat文件中,当然也可分别发送
java.io.ObjectInputStreamin=newjava.io.ObjectInputStream(
PrivateKeymyprikey=(PrivateKey)in.readObject();
//java.security.spec.X509EncodedKeySpecpubX509=
//newjava.security.spec.X509EncodedKeySpec(bX509);
//java.security.spec.X509EncodedKeySpecpubkeyEncode=
//java.security.spec.X509EncodedKeySpec
这是我的信息"
//要签名的信息
//用私钥对信息生成数字签名
java.security.Signaturesignet=java.security.Signature.getInstance("
signet.initSign(myprikey);
signet.update(myinfo.getBytes());
byte[]signed=signet.sign();
//对信息的数字签名
signed(签名内容)="
+byte2hex(signed));
//把信息和数字签名保存在一个文件中
java.io.ObjectOutputStreamout=newjava.io.ObjectOutputStream(
out.writeObject(myinfo);
out.writeObject(signed);
out.close();
签名并生成文件成功"
catch(java.lang.Exceptione){
e.printStackTrace();
签名并生成文件失败"
//第三步
//其他人通过公共方式得到此户的公钥和文件
//其他人用此户的公钥,对文件进行检查,如果成功说明是此用户发布的信息.
//
System.out.println(pubkey.getFormat());
in=newjava.io.ObjectInputStream(newjava.io.