|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
主要缺点就是:速度比较慢,没有C和C++快加密|算法对象
参数algorithm如:"DSA"
publicfinalvoidinitSign(PrivateKeyprivateKey)
throwsInvalidKeyException
用指定的私钥初始化
参数:privateKey所举行署名时用的私钥
publicfinalvoidupdate(bytedata)
throwsSignatureException
publicfinalvoidupdate(byte[]data)
throwsSignatureException
publicfinalvoidupdate(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("myprikey.dat")).exists()==false){
if(generatekey()==false){
System.out.println("天生密钥对败");
return;
};
}
//第二步,此用户
//从文件中读进私钥,对一个字符串举行署名后保留在一个文件(myinfo.dat)中
//而且再把myinfo.dat发送进来
//为了便利数字署名也放进了myifno.dat文件中,固然也可分离发送
try{
java.io.ObjectInputStreamin=newjava.io.ObjectInputStream(newjava.io.FileInputStream("myprikey.dat"));
PrivateKeymyprikey=(PrivateKey)in.readObject();
in.close();
//java.security.spec.X509EncodedKeySpecpubX509=newjava.security.spec.X509EncodedKeySpec(bX509);
//java.security.spec.X509EncodedKeySpecpubkeyEncode=java.security.spec.X509EncodedKeySpec
Stringmyinfo="这是我的信息";//要署名的信息
//用私钥对信息天生数字署名
java.security.Signaturesignet=java.security.Signature.getInstance("DSA");
signet.initSign(myprikey);
signet.update(myinfo.getBytes());
byte[]signed=signet.sign();//对信息的数字署名
System.out.println("signed(署名内容)="+byte2hex(signed));
//把信息和数字署名保留在一个文件中
java.io.ObjectOutputStreamout=newjava.io.ObjectOutputStream(newjava.io.FileOutputStream("myinfo.dat"));
out.writeObject(myinfo);
out.writeObject(signed);
out.close();
System.out.println("署名并天生文件乐成");
}
catch(java.lang.Exceptione){
e.printStackTrace();
System.out.println("署名并天生文件失利");
};
//第三步
//其别人经由过程大众体例失掉此户的公钥和文件
//其别人用此户的公钥,对文件举行反省,假如乐成申明是此用户公布的信息.
//
try{
java.io.ObjectInputStreamin=newjava.io.ObjectInputStream(newjava.io.FileInputStream("mypubkey.dat"));
PublicKeypubkey=(PublicKey)in.readObject();
in.close();
System.out.println(pubkey.getFormat());
in=newjava.io.ObjectInputStream(newjava.io.FileInputStream("myinfo.dat"));
Stringinfo=(String)in.readObject();
byte[]signed=(byte[])in.readObject();
in.close();
java.security.Signaturesignetcheck=java.security.Signature.getInstance("DSA");
signetcheck.initVerify(pubkey);
signetcheck.update(info.getBytes());
if(signetcheck.verify(signed)){
System.out.println("info="+info);
System.out.println("署名一般");
}
elseSystem.out.println("非署名一般");
}
catch(java.lang.Exceptione){e.printStackTrace();};
}
//天生一对文件myprikey.dat和mypubkey.dat---私钥和公钥,
//公钥要用户发送(文件,收集等办法)给别的用户,私钥保留在当地
publicbooleangeneratekey()
{
try{
java.security.KeyPairGeneratorkeygen=java.security.KeyPairGenerator.getInstance("DSA");
//SecureRandomsecrand=newSecureRandom();
//secrand.setSeed("tttt".getBytes());//初始化随机发生器
//keygen.initialize(576,secrand);//初始化密钥天生器
keygen.initialize(512);
KeyPairkeys=keygen.genKeyPair();
//KeyPairkeys=keygen.generateKeyPair();//天生密钥组
PublicKeypubkey=keys.getPublic();
PrivateKeyprikey=keys.getPrivate();
java.io.ObjectOutputStreamout=newjava.io.ObjectOutputStream(newjava.io.FileOutputStream("myprikey.dat"));
out.writeObject(prikey);
out.close();
System.out.println("写进对象prikeysok");
out=newjava.io.ObjectOutputStream(newjava.io.FileOutputStream("mypubkey.dat"));
out.writeObject(pubkey);
out.close();
System.out.println("写进对象pubkeysok");
System.out.println("天生密钥对乐成");
returntrue;
}
catch(java.lang.Exceptione){
e.printStackTrace();
System.out.println("天生密钥对失利");
returnfalse;
};
}
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.4.DESede/DES对称算法
起首天生密钥,并保留(这里并没的保留的代码,可参考DSA中的办法)
KeyGeneratorkeygen=KeyGenerator.getInstance(Algorithm);
SecretKeydeskey=keygen.generateKey();
用密钥加密明文(myinfo),天生密文(cipherByte)
Cipherc1=Cipher.getInstance(Algorithm);
c1.init(Cipher.ENCRYPT_MODE,deskey);
byte[]cipherByte=c1.doFinal(myinfo.getBytes());
传送密文和密钥,本文没有响应代码可参考DSA
.............
用密钥解密密文
c1=Cipher.getInstance(Algorithm);
c1.init(Cipher.DECRYPT_MODE,deskey);
byte[]clearByte=c1.doFinal(cipherByte);
绝对来讲对称密钥的利用是很复杂的,关于JCE来说支技DES,DESede,Blowfish三种加密术
关于密钥的保留各传送可以使用对象流大概用二进制编码,相干参考代码以下
SecretKeydeskey=keygen.generateKey();
byte[]desEncode=deskey.getEncoded();
javax.crypto.spec.SecretKeySpecdestmp=newjavax.crypto.spec.SecretKeySpec(desEncode,Algorithm);
SecretKeymydeskey=destmp;
相干API
KeyGenerator在DSA中已申明,在增加JCE后在instance进能够以下参数
DES,DESede,Blowfish,HmacMD5,HmacSHA1
javax.crypto.Cipher加/解密器
publicstaticfinalCiphergetInstance(java.lang.Stringtransformation)
throwsjava.security.NoSuchAlgorithmException,
NoSuchPaddingException
前往一个指定办法的Cipher对象
参数:transformation办法名(可用DES,DESede,Blowfish)
publicfinalvoidinit(intopmode,java.security.Keykey)
throwsjava.security.InvalidKeyException
用指定的密钥和形式初始化Cipher对象
参数:opmode体例(ENCRYPT_MODE,DECRYPT_MODE,WRAP_MODE,UNWRAP_MODE)
key密钥
publicfinalbyte[]doFinal(byte[]input)
throwsjava.lang.IllegalStateException,
IllegalBlockSizeException,
BadPaddingException
对input内的串,举行编码处置,前往处置后二进制串,是前往解密文仍是加解文由init时的opmode决意
注重:本办法的实行前假如有update,是对updat和本次input全体处置,不然是本inout的内容
/*
平安程序DESede/DES测试
*/
importjava.security.*;
importjavax.crypto.*;
publicclasstestdes{
publicstaticvoidmain(String[]args){
testdesmy=newtestdes();
my.run();
}
publicvoidrun(){
//增加新平安算法,假如用JCE就要把它增加出来
Security.addProvider(newcom.sun.crypto.provider.SunJCE());
StringAlgorithm="DES";//界说加密算法,可用DES,DESede,Blowfish
Stringmyinfo="要加密的信息";
try{
//天生密钥
KeyGeneratorkeygen=KeyGenerator.getInstance(Algorithm);
SecretKeydeskey=keygen.generateKey();
//加密
System.out.println("加密前的二进串:"+byte2hex(myinfo.getBytes()));
System.out.println("加密前的信息:"+myinfo);
Cipherc1=Cipher.getInstance(Algorithm);
c1.init(Cipher.ENCRYPT_MODE,deskey);
byte[]cipherByte=c1.doFinal(myinfo.getBytes());
System.out.println("加密后的二进串:"+byte2hex(cipherByte));
//解密
c1=Cipher.getInstance(Algorithm);
c1.init(Cipher.DECRYPT_MODE,deskey);
byte[]clearByte=c1.doFinal(cipherByte);
System.out.println("解密后的二进串:"+byte2hex(clearByte));
System.out.println("解密后的信息:"+(newString(clearByte)));
}
catch(java.security.NoSuchAlgorithmExceptione1){e1.printStackTrace();}
catch(javax.crypto.NoSuchPaddingExceptione2){e2.printStackTrace();}
catch(java.lang.Exceptione3){e3.printStackTrace();}
}
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.5.Diffie-Hellman密钥分歧协定
公然密钥暗码体系体例的奠定人Diffie和Hellman所提出的"指数密钥分歧协定"(ExponentialKeyAgreementProtocol),该协定不请求其余平安性先决前提,同意两名用户在公然媒体上互换信息以天生"分歧"的,能够共享的密钥。在JCE的中完成用户alice天生DH范例的密钥对,假如长度用1024天生的工夫请,保举第一次天生后保留DHParameterSpec,以便下次利用间接初始化.使其速率加速
System.out.println("ALICE:发生DH对...");
KeyPairGeneratoraliceKpairGen=KeyPairGenerator.getInstance("DH");
aliceKpairGen.initialize(512);
KeyPairaliceKpair=aliceKpairGen.generateKeyPair();
alice天生公钥发送组bob
byte[]alicePubKeyEnc=aliceKpair.getPublic().getEncoded();
bob从alice发送来的公钥中读出DH密钥对的初始参数天生bob的DH密钥对
注重这一步必定要做,要包管每一个用户用不异的初始参数天生的
DHParameterSpecdhParamSpec=((DHPublicKey)alicePubKey).getParams();
KeyPairGeneratorbobKpairGen=KeyPairGenerator.getInstance("DH");
bobKpairGen.initialize(dhParamSpec);
KeyPairbobKpair=bobKpairGen.generateKeyPair();
bob依据alice的公钥天生当地的DES密钥
KeyAgreementbobKeyAgree=KeyAgreement.getInstance("DH");
bobKeyAgree.init(bobKpair.getPrivate());
bobKeyAgree.doPhase(alicePubKey,true);
SecretKeybobDesKey=bobKeyAgree.generateSecret("DES");
bob已天生了他的DES密钥,他现把他的公钥发给alice,
byte[]bobPubKeyEnc=bobKpair.getPublic().getEncoded();
alice依据bob的公钥天生当地的DES密钥
,,,,,,解码
KeyAgreementaliceKeyAgree=KeyAgreement.getInstance("DH");
aliceKeyAgree.init(aliceKpair.getPrivate());
aliceKeyAgree.doPhase(bobPubKey,true);
SecretKeyaliceDesKey=aliceKeyAgree.generateSecret("DES");
bob和alice能过这个历程就天生了不异的DES密钥,在这类基本便可举行平安能信
经常使用API
java.security.KeyPairGenerator密钥天生器类
publicstaticKeyPairGeneratorgetInstance(Stringalgorithm)
throwsNoSuchAlgorithmException
以指定的算法前往一个KeyPairGenerator对象
参数:algorithm算法名.如:本来是DSA,如今增加了DiffieHellman(DH)
publicvoidinitialize(intkeysize)
以指定的长度初始化KeyPairGenerator对象,假如没有初始化体系以1024长度默许设置
参数:keysize算法位长.其局限必需在512到1024之间,且必需为64的倍数
注重:假如用1024发展的工夫很长,最好天生一次后就保留,下次就不必天生了
publicvoidinitialize(AlgorithmParameterSpecparams)
throwsInvalidAlgorithmParameterException
以指定参数初始化
javax.crypto.interfaces.DHPublicKey
publicDHParameterSpecgetParams()
前往
java.security.KeyFactory
publicstaticKeyFactorygetInstance(Stringalgorithm)
throwsNoSuchAlgorithmException
以指定的算法前往一个KeyFactory
参数:algorithm算法名:DSH,DH
publicfinalPublicKeygeneratePublic(KeySpeckeySpec)
throwsInvalidKeySpecException
依据指定的key申明,前往一个PublicKey对象
java.security.spec.X509EncodedKeySpec
publicX509EncodedKeySpec(byte[]encodedKey)
依据指定的二进制编码的字串天生一个key的申明
参数:encodedKey二进制编码的字串(一样平常能过PublicKey.getEncoded()天生)
javax.crypto.KeyAgreement暗码一至类
publicstaticfinalKeyAgreementgetInstance(java.lang.Stringalgorithm)
throwsjava.security.NoSuchAlgorithmException
前往一个指定算法的KeyAgreement对象
参数:algorithm算法名,如今只能是DiffieHellman(DH)
publicfinalvoidinit(java.security.Keykey)
throwsjava.security.InvalidKeyException
用指定的私钥初始化
参数:key一个私钥
publicfinaljava.security.KeydoPhase(java.security.Keykey,
booleanlastPhase)
throwsjava.security.InvalidKeyException,
java.lang.IllegalStateException
用指定的公钥举行定位,lastPhase断定这是不是是最初一个公钥,关于两个用户的
情形下就能够屡次定次,最初断定
参数:key公钥
lastPhase是不是最初公钥
publicfinalSecretKeygenerateSecret(java.lang.Stringalgorithm)
throwsjava.lang.IllegalStateException,
java.security.NoSuchAlgorithmException,
java.security.InvalidKeyException
依据指定的算法天生密钥
参数:algorithm加密算法(可用DES,DESede,Blowfish)
*/
importjava.io.*;
importjava.math.BigInteger;
importjava.security.*;
importjava.security.spec.*;
importjava.security.interfaces.*;
importjavax.crypto.*;
importjavax.crypto.spec.*;
importjavax.crypto.interfaces.*;
importcom.sun.crypto.provider.SunJCE;
publicclasstestDHKey{
publicstaticvoidmain(Stringargv[]){
try{
testDHKeymy=newtestDHKey();
my.run();
}catch(Exceptione){
System.err.println(e);
}
}
privatevoidrun()throwsException{
Security.addProvider(newcom.sun.crypto.provider.SunJCE());
System.out.println("ALICE:发生DH对...");
KeyPairGeneratoraliceKpairGen=KeyPairGenerator.getInstance("DH");
aliceKpairGen.initialize(512);
KeyPairaliceKpair=aliceKpairGen.generateKeyPair();//天生工夫长
//张三(Alice)天生大众密钥alicePubKeyEnc并发送给李四(Bob),
//好比用文件体例,socket.....
byte[]alicePubKeyEnc=aliceKpair.getPublic().getEncoded();
//bob吸收到alice的编码后的公钥,将其解码
KeyFactorybobKeyFac=KeyFactory.getInstance("DH");
X509EncodedKeySpecx509KeySpec=newX509EncodedKeySpec(alicePubKeyEnc);
PublicKeyalicePubKey=bobKeyFac.generatePublic(x509KeySpec);
System.out.println("alice公钥bob解码乐成");
//bob必需用不异的参数初始化的他的DHKEY对,以是要从Alice发给他的公然密钥,
//中读出参数,再用这个参数初始化他的DHkey对
//从alicePubKye中取alice初始化时用的参数
DHParameterSpecdhParamSpec=((DHPublicKey)alicePubKey).getParams();
KeyPairGeneratorbobKpairGen=KeyPairGenerator.getInstance("DH");
bobKpairGen.initialize(dhParamSpec);
KeyPairbobKpair=bobKpairGen.generateKeyPair();
System.out.println("BOB:天生DHkey对乐成");
KeyAgreementbobKeyAgree=KeyAgreement.getInstance("DH");
bobKeyAgree.init(bobKpair.getPrivate());
System.out.println("BOB:初始化当地key乐成");
//李四(bob)天生当地的密钥bobDesKey
bobKeyAgree.doPhase(alicePubKey,true);
SecretKeybobDesKey=bobKeyAgree.generateSecret("DES");
System.out.println("BOB:用alice的公钥定位当地key,天生当地DES密钥乐成");
//Bob天生大众密钥bobPubKeyEnc并发送给Alice,
//好比用文件体例,socket.....,使其天生当地密钥
byte[]bobPubKeyEnc=bobKpair.getPublic().getEncoded();
System.out.println("BOB向ALICE发送公钥");
//alice吸收到bobPubKeyEnc后天生bobPubKey
//再举行定位,使aliceKeyAgree定位在bobPubKey
KeyFactoryaliceKeyFac=KeyFactory.getInstance("DH");
x509KeySpec=newX509EncodedKeySpec(bobPubKeyEnc);
PublicKeybobPubKey=aliceKeyFac.generatePublic(x509KeySpec);
System.out.println("ALICE吸收BOB公钥并解码乐成");
;
KeyAgreementaliceKeyAgree=KeyAgreement.getInstance("DH");
aliceKeyAgree.init(aliceKpair.getPrivate());
System.out.println("ALICE:初始化当地key乐成");
aliceKeyAgree.doPhase(bobPubKey,true);
//张三(alice)天生当地的密钥aliceDesKey
SecretKeyaliceDesKey=aliceKeyAgree.generateSecret("DES");
System.out.println("ALICE:用bob的公钥定位当地key,并天生当地DES密钥");
if(aliceDesKey.equals(bobDesKey))System.out.println("张三和李四的密钥不异");
//如今张三和李四的当地的deskey是不异的以是,完整能够举行发送加密,吸收后解密,到达
//平安通道的的目标
/*
*bob用bobDesKey密钥加密信息
*/
CipherbobCipher=Cipher.getInstance("DES");
bobCipher.init(Cipher.ENCRYPT_MODE,bobDesKey);
Stringbobinfo="这是李四的秘密信息";
System.out.println("李四加密前原文:"+bobinfo);
byte[]cleartext=bobinfo.getBytes();
byte[]ciphertext=bobCipher.doFinal(cleartext);
/*
*alice用aliceDesKey密钥解密
*/
CipheraliceCipher=Cipher.getInstance("DES");
aliceCipher.init(Cipher.DECRYPT_MODE,aliceDesKey);
byte[]recovered=aliceCipher.doFinal(ciphertext);
System.out.println("alice解密bob的信息:"+(newString(recovered)));
if(!java.util.Arrays.equals(cleartext,recovered))
thrownewException("解密后与原文信息分歧");
System.out.println("解密后不异");
}
}
第3章小结
在加密术中天生密钥对时,密钥对确当然是越长越好,但费时也越多,请从中从实践动身拔取符合的长度,年夜部分例码中的密钥是每次运转就重新天生,在实践的情形中是天生后在一段工夫保留在文件中,再次运转间接从文件中读进,从而加速速率。固然准时更新和增强密钥保管的平安性也是必需的。
认真的记,感觉很紧张根本就没有时间和能力,来对技术知识点进行思考。这样课下就只能对知识进行简单的理解,其实简单的理解就是记忆课堂上讲的知识点, |
|