Java加密算法的实现实例细节分析讲解
2010-05-27 15:09
651 查看
第1章 基础知识
1.1、单钥密码体制
单钥密码体制是一种传统的加密算法,是指信息的发送方和接收方共同使用同一把密钥进行加解密。
通常,使用的加密算法比较简便高效,密钥简短,加解密速度快,破译极其困难。但是加密的安全性依靠密钥保管的安全性,在公开的计算机网络上安全地传送和保管密钥是一个严峻的问题,并且如果在多用户的情况下密钥的保管安全性也是一个问题。
单钥密码体制的代表是美国的DES
1.2、消息摘要
一个消息摘要就是一个数据块的数字指纹。即对一个任意长度的一个数据块进行计算,产生一个唯一指印(对于SHA1是产生一个20字节的二进制数组)。
消息摘要有两个基本属性:
两个不同的报文难以生成相同的摘要
难以对指定的摘要生成一个报文,而由该报文反推算出该指定的摘要
代表:美国国家标准技术研究所的SHA1和麻省理工学院Ronald Rivest提出的MD5
1.3、Diffie-Hellman密钥一致协议
密钥一致协议是由公开密钥密码体制的奠基人Diffie和Hellman所提出的一种思想。先决条件,允许两名用户在公开媒体上交换信息以生成"一致"的,可以共享的密钥
代表:指数密钥一致协议(Exponential Key Agreement Protocol)
1.4、非对称算法与公钥体系
1976年,Dittie和Hellman为解决密钥管理问题,在他们的奠基性的工作"密码学的新方向"一文中,提出一种密钥交换协议,允许在不安全的媒体上通过通讯双方交换信息,安全地传送秘密密钥。
在此新思想的基础上,很快出现了非对称密钥密码体制,即公钥密码体制。在公钥体制中,加密密钥不同于解密密钥,加密密钥公之于众,谁都可以使用;解密密钥只有解密人自己知道。它们分别称为公开密钥(Public key)和秘密密钥(Private key)。
迄今为止的所有公钥密码体系中,RSA系统是最著名、最多使用的一种。RSA公开密钥密码系统是由R.Rivest、A.Shamir和L.Adleman俊教授于1977年提出的。RSA的取名就是来自于这三位发明者的姓的第一个字母
1.5、数字签名
所谓数字签名就是信息发送者用其私钥对从所传报文中提取出的特征数据(或称数字指纹)进行RSA算法操作,以保证发信人无法抵赖曾发过该信息(即不可抵赖性),同时也确保信息报文在经签名后末被篡改(即完整性)。当信息接收者收到报文后,就可以用发送者的公钥对数字签名进行验证。
在数字签名中有重要作用的数字指纹是通过一类特殊的散列函数(HASH函数)生成的,对这些HASH函数的特殊要求是:
接受的输入报文数据没有长度限制;
对任何输入报文数据生成固定长度的摘要(数字指纹)输出
从报文能方便地算出摘要;
难以对指定的摘要生成一个报文,而由该报文反推算出该指定的摘要;
两个不同的报文难以生成相同的摘要
代表:DSA
第2章 在Java中的实现
2.1、相关
Diffie-Hellman密钥一致协议和DES程序需要JCE工具库的支持,可以到 http://Java.sun.com/security/index.html 下载JCE,并进行安装。简易安装把
jce1.2.1/lib下的所有内容复制到%Java_home%/lib/ext下,如果没有ext目录自行建立
,再把jce1_2_1.jar和sunjce_provider.jar添加到CLASSPATH内。
2.2、消息摘要MD5和SHA的使用
使用方法:
首先用生成一个MessageDigest类,确定计算方法
添加要进行计算摘要的信息
计算出摘要
发送给其他人你的信息和摘要
其他人用相同的方法初始化,添加信息,最后进行比较摘要是否相同
相关AIP
Java.security.MessageDigest 类
static getInstance(String algorithm)
返回一个MessageDigest对象,它实现指定的算法
参数:算法名,如 SHA-1 或MD5
添加要进行计算摘要的信息
完成计算,返回计算得到的摘要(对于MD5是16位,SHA是20位)
复位
比效两个摘要是否相同
代码:
2.3、数字签名DSA
对于一个用户来讲首先要生成他的密钥对,并且分别保存生成一个KeyPairGenerator实例:
如果设定随机产生器就用如相代码初始化
否则
生成密钥公钥pubkey和私钥prikey
分别保存在myprikey.dat和mypubkey.dat中,以便下次不在生成
用他私人密钥(prikey)对他所确认的信息(info)进行数字签名产生一个签名数组
从文件中读入私人密钥(prikey)
初始一个Signature对象,并用私钥对信息签名
把信息和签名保存在一个文件中(myinfo.dat)
把他的公钥的信息及签名发给其它用户
其他用户用他的公共密钥(pubkey)和签名(signed)和信息(info)进行验证是否由他签名的信息
读入公钥
读入签名和信息
初始一个Signature对象,并用公钥和签名进行验证:
对于密钥的保存本文是用对象流的方式保存和传送的,也可可以用编码的方式保存.注意要
具休说明如下:
public key是用X.509编码的,例码如下:
对于Private key是用PKCS#8编码,例码如下:
常用API
Java.security.KeyPairGenerator 密钥生成器类
以指定的算法返回一个KeyPairGenerator 对象
参数: algorithm 算法名.如:"DSA","RSA"
以指定的长度初始化KeyPairGenerator对象,如果没有初始化系统以1024长度默认设置
参数:keysize 算法位长.其范围必须在 512 到 1024 之间,且必须为 64 的倍数
public void initialize(int keysize, SecureRandom random)
以指定的长度初始化和随机发生器初始化KeyPairGenerator对象
参数:keysize 算法位长.其范围必须在 512 到 1024 之间,且必须为 64 的倍数
random 一个随机位的来源(对于initialize(int keysize)使用了默认随机器:
2.4、DESede/DES对称算法
首先生成密钥,并保存(这里并没的保存的代码,可参考DSA中的方法)
用密钥加密明文(myinfo),生成密文(cipherByte)
传送密文和密钥
用密钥解密密文
相对来说对称密钥的使用是很简单的,对于JCE来讲支技DES,DESede,Blowfish三种加密术,对于密钥的保存各传送可使用对象流或者用二进制编码,相关参考代码如下:
相关API
KeyGenerator 在DSA中已经说明,在添加JCE后在instance进可以如下参数:
返回一个指定方法的Cipher对象
参数:transFORMation 方法名(可用 DES,DESede,Blowfish)
用指定的密钥和模式初始化Cipher对象
参数:opmode 方式(ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE,UNWRAP_MODE)
key 密钥
对input内的串,进行编码处理,返回处理后二进制串,是返回解密文还是加解文由init时的opmode决定。
注意:本方法的执行前如果有update,是对updat和本次input全部处理,否则是本inout的内容
2.5、Diffie-Hellman密钥一致协议
公开密钥密码体制的奠基人Diffie和Hellman所提出的"指数密钥一致协议"(Exponential Key Agreement Protocol),该协议不要求别的安全性为先决条件,允许两名用户在公开媒体上交换信息以生成"一致"的,可以共享的密钥。
在JCE的中实现用户alice生成DH类型的密钥对,如果长度用1024生成的时间请,推荐第一次生成后保存DHParameterSpec,以便下次使用直接初始化.使其速度加快。
alice生成公钥发送组bob byte[] alicePubKeyEnc =
aliceKpair.getPublic().getEncoded();
bob从alice发送来的公钥中读出DH密钥对的初始参数生成bob的DH密钥对,注意这一步一定要做,要保证每个用户用相同的初始参数生成的:
bob根据alice的公钥生成本地的DES密钥:
bob已经生成了他的DES密钥,他现把他的公钥发给alice:
alice根据bob的公钥生成本地的DES密钥
bob和alice能过这个过程就生成了相同的DES密钥。
常用API
Java.security.KeyPairGenerator 密钥生成器类
public static KeyPairGenerator getInstance(String algorithm)
throws NoSuchAlgorithmException
以指定的算法返回一个KeyPairGenerator 对象
参数: algorithm 算法名.如:原来是DSA,现在添加了 DiffieHellman(DH)
public void initialize(int keysize)
以指定的长度初始化KeyPairGenerator对象,如果没有初始化系统以1024长度默认设置
参数:keysize 算法位长.其范围必须在 512 到 1024 之间,且必须为 64 的倍数
注意:如果用1024生长的时间很长,最好生成一次后就保存,下次就不用生成了
第3章 小结
在加密术中生成密钥对时,密钥对的当然是越长越好,但费时也越多,请从中从实际出发选取合适的长度,大部分例码中的密钥是每次运行就从新生成,在实际的情况中是生成后在一段时间保存在文件中,再次运行直接从文件中读入,从而加快速度。当然定时更新和加强密钥保管的安全性也是必须的。
摘自:http://tech.ccidnet.com/art/322/20051102/363689_1.html
1.1、单钥密码体制
单钥密码体制是一种传统的加密算法,是指信息的发送方和接收方共同使用同一把密钥进行加解密。
通常,使用的加密算法比较简便高效,密钥简短,加解密速度快,破译极其困难。但是加密的安全性依靠密钥保管的安全性,在公开的计算机网络上安全地传送和保管密钥是一个严峻的问题,并且如果在多用户的情况下密钥的保管安全性也是一个问题。
单钥密码体制的代表是美国的DES
1.2、消息摘要
一个消息摘要就是一个数据块的数字指纹。即对一个任意长度的一个数据块进行计算,产生一个唯一指印(对于SHA1是产生一个20字节的二进制数组)。
消息摘要有两个基本属性:
两个不同的报文难以生成相同的摘要
难以对指定的摘要生成一个报文,而由该报文反推算出该指定的摘要
代表:美国国家标准技术研究所的SHA1和麻省理工学院Ronald Rivest提出的MD5
1.3、Diffie-Hellman密钥一致协议
密钥一致协议是由公开密钥密码体制的奠基人Diffie和Hellman所提出的一种思想。先决条件,允许两名用户在公开媒体上交换信息以生成"一致"的,可以共享的密钥
代表:指数密钥一致协议(Exponential Key Agreement Protocol)
1.4、非对称算法与公钥体系
1976年,Dittie和Hellman为解决密钥管理问题,在他们的奠基性的工作"密码学的新方向"一文中,提出一种密钥交换协议,允许在不安全的媒体上通过通讯双方交换信息,安全地传送秘密密钥。
在此新思想的基础上,很快出现了非对称密钥密码体制,即公钥密码体制。在公钥体制中,加密密钥不同于解密密钥,加密密钥公之于众,谁都可以使用;解密密钥只有解密人自己知道。它们分别称为公开密钥(Public key)和秘密密钥(Private key)。
迄今为止的所有公钥密码体系中,RSA系统是最著名、最多使用的一种。RSA公开密钥密码系统是由R.Rivest、A.Shamir和L.Adleman俊教授于1977年提出的。RSA的取名就是来自于这三位发明者的姓的第一个字母
1.5、数字签名
所谓数字签名就是信息发送者用其私钥对从所传报文中提取出的特征数据(或称数字指纹)进行RSA算法操作,以保证发信人无法抵赖曾发过该信息(即不可抵赖性),同时也确保信息报文在经签名后末被篡改(即完整性)。当信息接收者收到报文后,就可以用发送者的公钥对数字签名进行验证。
在数字签名中有重要作用的数字指纹是通过一类特殊的散列函数(HASH函数)生成的,对这些HASH函数的特殊要求是:
接受的输入报文数据没有长度限制;
对任何输入报文数据生成固定长度的摘要(数字指纹)输出
从报文能方便地算出摘要;
难以对指定的摘要生成一个报文,而由该报文反推算出该指定的摘要;
两个不同的报文难以生成相同的摘要
代表:DSA
第2章 在Java中的实现
2.1、相关
Diffie-Hellman密钥一致协议和DES程序需要JCE工具库的支持,可以到 http://Java.sun.com/security/index.html 下载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.MessageDigest alga=Java.security.MessageDigest.getInstance("SHA-1"); |
添加要进行计算摘要的信息
alga.update(myinfo.getBytes()); |
计算出摘要
byte[] digesta=alga.digest(); |
发送给其他人你的信息和摘要
其他人用相同的方法初始化,添加信息,最后进行比较摘要是否相同
algb.isEqual(digesta,algb.digest()) |
相关AIP
Java.security.MessageDigest 类
static getInstance(String algorithm)
返回一个MessageDigest对象,它实现指定的算法
参数:算法名,如 SHA-1 或MD5
void update (byte input) void update (byte[] input) void update(byte[] input, int offset, int len) |
添加要进行计算摘要的信息
byte[] digest() |
完成计算,返回计算得到的摘要(对于MD5是16位,SHA是20位)
void reset() |
复位
static boolean isEqual (byte[] digesta, byte[] digestb) |
比效两个摘要是否相同
代码:
import Java.security.*; public class myDigest { public static void main(String[] args) { myDigest my=new myDigest(); my.testDigest(); } public void testDigest() { try { String myinfo="我的测试信息"; //Java.security.MessageDigest alg= Java.security.MessageDigest.getInstance("MD5"); Java.security.MessageDigest alga= Java.security.MessageDigest.getInstance("SHA-1"); alga.update(myinfo.getBytes()); byte[] digesta=alga.digest(); System.out.println ("本信息摘要是:"+byte2hex(digesta)); //通过某中方式传给其他人你的信息 (myinfo)和摘要(digesta) 对方可以判断是否更改或传输正常 Java.security.MessageDigest algb= Java.security.MessageDigest.getInstance ("SHA-1"); algb.update(myinfo.getBytes()); if (algb.isEqual(digesta,algb.digest())) { System.out.println("信息检查正常"); } else { System.out.println("摘要不相同"); } } catch (Java.security.NoSuchAlgorithmException ex) { System.out.println("非法摘要算法"); } } public String byte2hex(byte[] b) //二行制转字符串 { String hs=""; String stmp=""; for (int n=0;n { stmp=(Java.lang.Integer.toHexString (b & 0XFF)); if (stmp.length()==1) hs=hs+"0"+stmp; else hs=hs+stmp; if (n } return hs.toUpperCase(); } } |
对于一个用户来讲首先要生成他的密钥对,并且分别保存生成一个KeyPairGenerator实例:
Java.security.KeyPairGenerator keygen= Java.security.KeyPairGenerator.getInstance("DSA"); |
SecureRandom secrand=new SecureRandom(); secrand.setSeed("tttt".getBytes()); //初始化随机产生器 keygen.initialize(512,secrand); //初始化密钥生成器 |
keygen.initialize(512); |
KeyPair keys=keygen.generateKeyPair(); //生成密钥组 PublicKey pubkey=keys.getPublic(); PrivateKey prikey=keys.getPrivate(); |
Java.io.ObjectOutputStream out= new Java.io.ObjectOutputStream(new Java.io.FileOutputStream("myprikey.dat")); out.writeObject(prikey); out.close(); out=new Java.io.ObjectOutputStream(new Java.io.FileOutputStream("mypubkey.dat")); out.writeObject(pubkey); out.close(); |
从文件中读入私人密钥(prikey)
Java.io.ObjectInputStream in= new Java.io.ObjectInputStream(new Java.io.FileInputStream("myprikey.dat")); PrivateKey myprikey= (PrivateKey)in.readObject(); in.close(); |
Java.security.Signature signet=Java.security.Signature.getInstance("DSA"); signet.initSign(myprikey); signet.update(myinfo.getBytes()); byte[] signed=signet.sign(); |
Java.io.ObjectOutputStream out= new Java.io.ObjectOutputStream(new Java.io.FileOutputStream("myinfo.dat")); out.writeObject(myinfo); out.writeObject(signed); out.close(); |
其他用户用他的公共密钥(pubkey)和签名(signed)和信息(info)进行验证是否由他签名的信息
读入公钥
Java.io.ObjectInputStream in= new Java.io.ObjectInputStream(new Java.io.FileInputStream("mypubkey.dat")); PublicKey pubkey= (PublicKey)in.readObject(); in.close(); |
in=new Java.io.ObjectInputStream(new Java.io.FileInputStream("myinfo.dat")); String info=(String)in.readObject(); byte[] signed=(byte[])in.readObject(); in.close(); |
signetcheck=Java.security. Signature.getInstance("DSA"); signetcheck.initVerify(pubkey); signetcheck.update(info.getBytes()); if (signetcheck.verify(signed)) { System.out.println("签名正常"); } |
import Java.security.spec.* import Java.security.* |
public key是用X.509编码的,例码如下:
byte[] bobEncodedPubKey=mypublic.getEncoded(); //生成编码 //传送二进制编码 //以下代码转换编码为相应key对象 X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(bobEncodedPubKey); KeyFactory keyFactory = KeyFactory.getInstance("DSA"); PublicKey bobPubKey = keyFactory.generatePublic(bobPubKeySpec); |
byte[] bPKCS=myprikey.getEncoded(); //传送二进制编码 //以下代码转换编码为相应key对象 PKCS8EncodedKeySpec priPKCS8= new PKCS8EncodedKeySpec(bPKCS); KeyFactory keyf= KeyFactory.getInstance("DSA"); PrivateKey otherprikey= keyf.generatePrivate(priPKCS8); |
Java.security.KeyPairGenerator 密钥生成器类
public static KeyPairGenerator getInstance(String algorithm) throws NoSuchAlgorithmException |
参数: algorithm 算法名.如:"DSA","RSA"
public void initialize(int keysize) |
参数:keysize 算法位长.其范围必须在 512 到 1024 之间,且必须为 64 的倍数
public void initialize(int keysize, SecureRandom random)
以指定的长度初始化和随机发生器初始化KeyPairGenerator对象
参数:keysize 算法位长.其范围必须在 512 到 1024 之间,且必须为 64 的倍数
random 一个随机位的来源(对于initialize(int keysize)使用了默认随机器:
public abstract KeyPair generateKeyPair() 产生新密钥对 Java.security.KeyPair 密钥对类 public PrivateKey getPrivate() 返回私钥 public PublicKey getPublic() 返回公钥 Java.security.Signature 签名类 public static Signature getInstance(String algorithm) throws NoSuchAlgorithmException 返回一个指定算法的Signature对象 参数 algorithm 如:"DSA" public final void initSign(PrivateKey privateKey) throws InvalidKeyException 用指定的私钥初始化 参数:privateKey 所进行签名时用的私钥 public final void update(byte data) throws SignatureException public final void update(byte[] data) throws SignatureException public final void update (byte[] data, int off, int len) throws SignatureException 添加要签名的信息 public final byte[] sign() throws SignatureException 返回签名的数组, 前提是initSign和update public final void initVerify (PublicKey publicKey) throws InvalidKeyException 用指定的公钥初始化 参数:publicKey 验证时用的公钥 public final boolean verify (byte[] signature) throws SignatureException 验证签名是否有效, 前提是已经initVerify初始化 参数: signature 签名数组 */ import Java.security.*; import Java.security.spec.*; public class testdsa { public static void main (String[] args) throws Java.security.NoSuchAlgorithmException, Java.lang.Exception { testdsa my=new testdsa(); my.run(); } public void run() { //数字签名生成密钥 //第一步生成密钥对,如果已经生成过, 本过程就可以跳过,对用户来讲myprikey.dat要保存在本地 //而mypubkey.dat给发布给其它用户 if ((new Java.io.File ("myprikey.dat")).exists()==false) { if (generatekey()==false) { System.out.println("生成密钥对败"); return; }; } //第二步,此用户 //从文件中读入私钥, 对一个字符串进行签名后保存在一个文件(myinfo.dat)中 //并且再把myinfo.dat发送出去 //为了方便数字签名也放进了myifno.dat文件中, 当然也可分别发送 try { Java.io.ObjectInputStream in= new Java.io.ObjectInputStream(new Java.io.FileInputStream("myprikey.dat")); PrivateKey myprikey= (PrivateKey)in.readObject(); in.close(); // Java.security.spec.X509EncodedKeySpec pubX509= new Java.security.spec .X509EncodedKeySpec(bX509); //Java.security.spec.X509EncodedKeySpec pubkeyEncode= Java.security.spec.X509EncodedKeySpec String myinfo="这是我的信息"; //要签名的信息 //用私钥对信息生成数字签名 Java.security.Signature signet=Java.security. Signature.getInstance("DSA"); signet.initSign(myprikey); signet.update(myinfo.getBytes()); byte[] signed=signet.sign(); //对信息的数字签名 System.out.println("signed(签名内容) ="+byte2hex(signed)); //把信息和数字签名保存在一个文件中 Java.io.ObjectOutputStream out= new Java.io.ObjectOutputStream(new Java.io.FileOutputStream("myinfo.dat")); out.writeObject(myinfo); out.writeObject(signed); out.close(); System.out.println ("签名并生成文件成功"); } catch (Java.lang.Exception e) { e.printStackTrace(); System.out.println ("签名并生成文件失败"); }; //第三步 //其他人通过公共方式得到此户的公钥和文件 //其他人用此户的公钥,对文件进行检查, 如果成功说明是此用户发布的信息. // try { Java.io.ObjectInputStream in= new Java.io.ObjectInputStream(new Java.io.FileInputStream("mypubkey.dat")); PublicKey pubkey=(PublicKey)in.readObject(); in.close(); System.out.println(pubkey.getFORMat()); in=new Java.io.ObjectInputStream(new Java.io.FileInputStream("myinfo.dat")); String info=(String)in.readObject(); byte[] signed=(byte[])in.readObject(); in.close(); Java.security.Signature signetcheck=Java.security. Signature.getInstance("DSA"); signetcheck.initVerify(pubkey); signetcheck.update(info.getBytes()); if (signetcheck.verify(signed)) { System.out.println("info="+info); System.out.println("签名正常"); } else System.out.println("非签名正常"); } catch (Java.lang.Exception e) {e.printStackTrace();}; } //生成一对文件myprikey.dat 和mypubkey.dat---私钥和公钥, //公钥要用户发送(文件,网络等方法)给其它用户, 私钥保存在本地 public boolean generatekey() { try { Java.security.KeyPairGenerator keygen=Java.security. KeyPairGenerator.getInstance("DSA"); // SecureRandom secrand=new SecureRandom(); // secrand.setSeed("tttt".getBytes()); //初始化随机产生器 // keygen.initialize(576,secrand); //初始化密钥生成器 keygen.initialize(512); KeyPair keys=keygen.genKeyPair(); // KeyPair keys=keygen.generateKeyPair(); //生成密钥组 PublicKey pubkey=keys.getPublic(); PrivateKey prikey=keys.getPrivate(); Java.io.ObjectOutputStream out= new Java.io.ObjectOutputStream(new Java.io.FileOutputStream("myprikey.dat")); out.writeObject(prikey); out.close(); System.out.println("写入对象 prikeys ok"); out=new Java.io.ObjectOutputStream(new Java.io.FileOutputStream("mypubkey.dat")); out.writeObject(pubkey); out.close(); System.out.println("写入对象 pubkeys ok"); System.out.println("生成密钥对成功"); return true; } catch (Java.lang.Exception e) { e.printStackTrace(); System.out.println("生成密钥对失败"); return false; }; } public String byte2hex(byte[] b) { String hs=""; String stmp=""; for (int n=0;n { stmp=(Java.lang.Integer.toHexString(b & 0XFF)); if (stmp.length()==1) hs=hs+"0"+stmp; else hs=hs+stmp; if (n } return hs.toUpperCase(); } } |
首先生成密钥,并保存(这里并没的保存的代码,可参考DSA中的方法)
KeyGenerator keygen = KeyGenerator.getInstance(Algorithm); SecretKey deskey = keygen.generateKey(); |
用密钥加密明文(myinfo),生成密文(cipherByte)
Cipher c1 = Cipher.getInstance(Algorithm); c1.init(Cipher.ENCRYPT_MODE,deskey); byte[] cipherByte= c1.doFinal(myinfo.getBytes()); |
传送密文和密钥
用密钥解密密文
c1 = Cipher.getInstance(Algorithm); c1.init(Cipher.DECRYPT_MODE,deskey); byte[] clearByte=c1.doFinal(cipherByte); |
相对来说对称密钥的使用是很简单的,对于JCE来讲支技DES,DESede,Blowfish三种加密术,对于密钥的保存各传送可使用对象流或者用二进制编码,相关参考代码如下:
SecretKey deskey = keygen.generateKey(); byte[] desEncode= deskey.getEncoded(); Javax.crypto.spec.SecretKeySpec destmp=new Javax.crypto.spec. SecretKeySpec(desEncode,Algorithm); SecretKey mydeskey=destmp; |
KeyGenerator 在DSA中已经说明,在添加JCE后在instance进可以如下参数:
DES,DESede,Blowfish,HmacMD5,HmacSHA1 Javax.crypto.Cipher 加/解密器 public static final Cipher getInstance (Java.lang.String transFORMation) throws Java.security. NoSuchAlgorithmException, NoSuchPaddingException |
参数:transFORMation 方法名(可用 DES,DESede,Blowfish)
public final void init(int opmode, Java.security.Key key) throws Java.security.InvalidKeyException |
用指定的密钥和模式初始化Cipher对象
参数:opmode 方式(ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE,UNWRAP_MODE)
key 密钥
public final byte[] doFinal(byte[] input) throws Java.lang.IllegalStateException, IllegalBlockSizeException, BadPaddingException |
对input内的串,进行编码处理,返回处理后二进制串,是返回解密文还是加解文由init时的opmode决定。
注意:本方法的执行前如果有update,是对updat和本次input全部处理,否则是本inout的内容
/* 安全程序 DESede/DES测试 */ import Java.security.*; import Javax.crypto.*; public class testdes { public static void main(String[] args) { testdes my=new testdes(); my.run(); } public void run() { //添加新安全算法, 如果用JCE就要把它添加进去 Security.addProvider (new com.sun.crypto.provider.SunJCE()); String Algorithm="DES"; //定义 加密算法,可用 DES,DESede,Blowfish String myinfo="要加密的信息"; try { //生成密钥 KeyGenerator keygen = KeyGenerator.getInstance(Algorithm); SecretKey deskey = keygen.generateKey(); //加密 System.out.println ("加密前的二进串:"+ byte2hex(myinfo.getBytes())); System.out.println ("加密前的信息:"+myinfo); Cipher c1 = 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 ("解密后的信息:"+(new String(clearByte))); } catch (Java.security. NoSuchAlgorithmException e1) {e1.printStackTrace();} catch (Javax.crypto. NoSuchPaddingException e2) {e2.printStackTrace();} catch (Java.lang.Exception e3) {e3.printStackTrace();} } public String byte2hex(byte[] b) //二行制转字符串 { String hs=""; String stmp=""; for (int n=0;n { stmp= (Java.lang.Integer.toHexString (b & 0XFF)); if (stmp.length()==1) hs=hs+"0"+stmp; else hs=hs+stmp; if (n } return hs.toUpperCase(); } } |
公开密钥密码体制的奠基人Diffie和Hellman所提出的"指数密钥一致协议"(Exponential Key Agreement Protocol),该协议不要求别的安全性为先决条件,允许两名用户在公开媒体上交换信息以生成"一致"的,可以共享的密钥。
在JCE的中实现用户alice生成DH类型的密钥对,如果长度用1024生成的时间请,推荐第一次生成后保存DHParameterSpec,以便下次使用直接初始化.使其速度加快。
System.out.println("ALICE: 产生 DH 对 ..."); KeyPairGenerator aliceKpairGen = KeyPairGenerator.getInstance("DH"); aliceKpairGen.initialize(512); KeyPair aliceKpair = aliceKpairGen.generateKeyPair(); |
alice生成公钥发送组bob byte[] alicePubKeyEnc =
aliceKpair.getPublic().getEncoded();
bob从alice发送来的公钥中读出DH密钥对的初始参数生成bob的DH密钥对,注意这一步一定要做,要保证每个用户用相同的初始参数生成的:
DHParameterSpec dhParamSpec = ((DHPublicKey)alicePubKey).getParams(); KeyPairGenerator bobKpairGen = KeyPairGenerator.getInstance("DH"); bobKpairGen.initialize(dhParamSpec); KeyPair bobKpair = bobKpairGen.generateKeyPair(); |
KeyAgreement bobKeyAgree = KeyAgreement.getInstance("DH"); bobKeyAgree.init (bobKpair.getPrivate()); bobKeyAgree.doPhase (alicePubKey, true); SecretKey bobDesKey = bobKeyAgree.generateSecret("DES"); |
byte[] bobPubKeyEnc = bobKpair.getPublic().getEncoded(); |
KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH"); aliceKeyAgree.init (aliceKpair.getPrivate()); aliceKeyAgree.doPhase (bobPubKey, true); SecretKey aliceDesKey = aliceKeyAgree.generateSecret("DES"); |
常用API
Java.security.KeyPairGenerator 密钥生成器类
public static KeyPairGenerator getInstance(String algorithm)
throws NoSuchAlgorithmException
以指定的算法返回一个KeyPairGenerator 对象
参数: algorithm 算法名.如:原来是DSA,现在添加了 DiffieHellman(DH)
public void initialize(int keysize)
以指定的长度初始化KeyPairGenerator对象,如果没有初始化系统以1024长度默认设置
参数:keysize 算法位长.其范围必须在 512 到 1024 之间,且必须为 64 的倍数
注意:如果用1024生长的时间很长,最好生成一次后就保存,下次就不用生成了
public void initialize |
第3章 小结
在加密术中生成密钥对时,密钥对的当然是越长越好,但费时也越多,请从中从实际出发选取合适的长度,大部分例码中的密钥是每次运行就从新生成,在实际的情况中是生成后在一段时间保存在文件中,再次运行直接从文件中读入,从而加快速度。当然定时更新和加强密钥保管的安全性也是必须的。
摘自:http://tech.ccidnet.com/art/322/20051102/363689_1.html
相关文章推荐
- 网络爬虫讲解(附java实现的实例)
- 网络爬虫讲解(附Java实现的实例)
- Java实现二分查找算法实例分析
- java图的邻接表实现两种方式及实例应用分析
- Java Web应用程序实现基础的文件下载功能的实例讲解
- 网络爬虫讲解(附java实现的实例)
- Java ArrayList 实现实例讲解
- 实例讲解Java的多进程运行模式分析 --IT知道网(http://www.itwis.c...(转载)
- Java实现Web应用中的定时任务(实例讲解)
- 动态规划算法分析及实例——求解完全背包问题(java实现)
- 网络爬虫讲解(附java实现的实例)
- 网络爬虫讲解(附java实现的实例)
- [零基础学JAVA]Java SE应用部分-31.Java IO操作(05)IO操作实例讲解之实现简单MIS 推荐
- 网络爬虫讲解(附java实现的实例)
- java实现屏幕共享功能实例分析
- 【JAVA】42、实例讲解——类设计分析
- java图的邻接表实现两种方式及实例应用分析
- 网络爬虫讲解(附java实现的实例)
- java 实现第二个实例实现Bank ,进行简单的注册,简单的异常的分析!