`
沙舟狼客
  • 浏览: 162324 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

加密机制的发展(JCE/JCA)

阅读更多

一、对称密钥-------最原始的加密解密

      对称密钥最好的理解就是:加密和解密用同一个密钥,典型的例子就是凯撒密码,他的基本思想是:通过把字母移动一定的位数来实现加密和解密。例如,如果密匙是把明文字母的位数向后移动三位,那么明文字母B就变成了密文的E,依次类推,X将变成A,Y变成B,Z变成C,由此可见,位数就是凯撒密码加密和解密的密钥。 常见的对称加密算法有DES、3DES、IDEA、AES,这里用AES写个例子

byte[] plain = "password".getBytes();
		System.out.println("原文:"+Arrays.toString(plain));
		
		//生成AES Key
		KeyGenerator generator = KeyGenerator.getInstance("AES");
		SecretKey aesKey = generator.generateKey(); 
		
		//获取AES的Cipher
		Cipher cipher = Cipher.getInstance("AES");
		//初始化模式  加密
		cipher.init(Cipher.ENCRYPT_MODE,aesKey);
		cipher.update(plain);
		byte[] result1 = cipher.doFinal();
		System.out.println("加密结果:"+Arrays.toString(result1));
		
		//解密
		cipher.init(Cipher.DECRYPT_MODE, aesKey);
		cipher.update(result1);
		byte[] result2 = cipher.doFinal();
		
		System.out.println("解密结果:"+Arrays.toString(result2));
		System.out.println("原文比较:"+Arrays.equals(result2, plain));

 结果:

原文:[112, 97, 115, 115, 119, 111, 114, 100]
加密结果:[-31, -16, -80, 28, -127, -14, -128, -22, -57, -117, -86, -44, -119, -125, -80, -11]
解密结果:[112, 97, 115, 115, 119, 111, 114, 100]
原文比较:true

 二、非对称密钥加密

 又名“公开密钥加密算法”,对称密钥的缺点就是当得到那个key之后就不安全了,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey);公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能 解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。 非对称加密算法实现机密信息交换的基本过程是:甲方生成一对密钥并将其中的一把作为公用密钥向其它方公开;得到该公用密钥的乙方使用该密钥对机密信息进行 加密后再发送给甲方;甲方再用自己保存的另一把专用密钥对加密后的信息进行解密,说简单了就是publicKey和privateKey是一对,可以根据一定对应的关系得到另一半,比如y=3x+10;可以把x和y当做一个非对称密钥;典型的算法有 RSA、Elgamal、背包算法、Rabin、D-H、ECC(椭圆曲线加密算法)

//B给A发送的信息
		byte[] plain = "password".getBytes();
		System.out.println("原文:"+Arrays.toString(plain));
		
		//A生成一个密钥对
		KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
		generator.initialize(1024);
		KeyPair keyPair = generator.generateKeyPair();
		//A把公钥公开
		PublicKey publicKey = keyPair.getPublic();
		//A自己保存好私钥
		PrivateKey privateKey = keyPair.getPrivate();
		System.out.println("公钥:"+publicKey);
		System.out.println("私钥:"+privateKey);
		
		Cipher cipher = Cipher.getInstance("RSA");
		//B用A的公钥把信息加密后发给A
		cipher.init(Cipher.ENCRYPT_MODE,publicKey);
		cipher.update(plain);
		byte[] result1 = cipher.doFinal();
		System.out.println("加密结果:"+Arrays.toString(result1));
		
		//A得到B发过来的信息后用自己的私钥进行解密
		cipher.init(Cipher.DECRYPT_MODE, privateKey);
		cipher.update(result1);
		byte[] result2 = cipher.doFinal();
		System.out.println("解密结果:"+Arrays.toString(result2));
		
		System.out.println("原文比较:"+Arrays.equals(result2, plain));

三、签名算法的产生

当B给A发信息“我给你打过去了1000元”,被C截取,C把信息篡改为“你给我打1000元”发给A,这时A并不知道信息已经被C修改过,还认为是B发过来的信息,于是就给B打了了一千元!!!这样很不安全,于是就有了签名算法的产生,就是B把自己的信息进行签名(相当于盖个章),这时A就很容易识别信息没有修改过

//B给A发送的信息
		byte[] plain = "password".getBytes();
		System.out.println("原文:"+Arrays.toString(plain));
		
		KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
		generator.initialize(1024);
		
		//A生成一个密钥对
		KeyPair aKeyPair = generator.generateKeyPair();
		//A把公钥公开
		PublicKey aPublicKey = aKeyPair.getPublic();
		//A自己保存好私钥
		PrivateKey aPrivateKey = aKeyPair.getPrivate();
		System.out.println("A的公钥:"+aPublicKey);
		System.out.println("A的私钥:"+aPrivateKey);
		
		
		
		//B生成的一个密钥对
		KeyPair bKeyPair = generator.generateKeyPair();
		//B的公钥
		PublicKey bPublicKey = bKeyPair.getPublic();
		//B的私钥
		PrivateKey bPrivateKey = bKeyPair.getPrivate();
		System.out.println("B的公钥:"+aPublicKey);
		System.out.println("B的私钥:"+aPrivateKey);
		
		//第一步B操作
		//加密
		Cipher cipher = Cipher.getInstance("RSA");
		//B用A的公钥把信息加密
		cipher.init(Cipher.ENCRYPT_MODE,aPublicKey);
		cipher.update(plain);
		byte[] result1 = cipher.doFinal();
		System.out.println("加密结果:"+Arrays.toString(result1));
		
		//把原文做一个信息摘要
		MessageDigest digest = MessageDigest.getInstance("SHA1");
		digest.update(plain);
		byte[] hash = digest.digest();
		
		//签名
		Signature signature = Signature.getInstance("SHA1withRSA");
		//B用自己的私钥对信息签名
		signature.initSign(bPrivateKey);
		signature.update(hash);
		byte[] signByte = signature.sign();
		
		
		//B把签名结果signByte和加密结果result1一起发送给A
		
		
		//第二步A操作
		//A得到B发过来的信息后用自己的私钥进行解密
		cipher.init(Cipher.DECRYPT_MODE, aPrivateKey);
		cipher.update(result1);
		byte[] result2 = cipher.doFinal();
		System.out.println("解密结果:"+Arrays.toString(result2));
		System.out.println("原文比较:"+Arrays.equals(result2, plain));
		
		//把解密的结果进行信息摘要
		digest.reset();
		digest.update(result2);
		byte[] hash2 = digest.digest();
		
		//比较两次摘要的结果是否一致
		signature.initVerify(bPublicKey);
		signature.update(hash2);
		boolean b = signature.verify(signByte);
		System.out.println("验证签名结果:"+b);

 输出结果:

原文:[112, 97, 115, 115, 119, 111, 114, 100]
A的公钥:Sun RSA public key, 1024 bits
  modulus: 102539187515284730067999644651029605499155012515018193956264041032712042245940835316344273183723893202553260620259419073173666324899506874839042020529427319710557325844173671303708388890745691502555168128969439923835578562447745704520780863763243855014463806372707187192860875656087947756935417785902707236111
  public exponent: 65537
A的私钥:Sun RSA private CRT key, 1024 bits
  modulus:          102539187515284730067999644651029605499155012515018193956264041032712042245940835316344273183723893202553260620259419073173666324899506874839042020529427319710557325844173671303708388890745691502555168128969439923835578562447745704520780863763243855014463806372707187192860875656087947756935417785902707236111
  public exponent:  65537
  private exponent: 60911441005196298675210860520152487475587893742804420539715204868158635834364140252080487347842514705717396115283266611802859509813734259187310143906970630220845991871368219715775743370250594182491008406793730989043642353446311784524222989887596013598331427135510011783066371889013758659686178307766978183449
  prime p:          10952081096215932838370494255560322806855249435195895093365419505271086940019997647808658906999895561701787208823891331735140003545850379556296491139129413
  prime q:          9362529971651978753471787637908879302644842060847691470500031927265884682918029490403020820378706946420421723488722740493564033473307756625205829732314947
  prime exponent p: 2815686015382795251441238654682635442157927548310353486246150315765331703501791970458337945344480832493300161458012192325028211845889086243557678551096197
  prime exponent q: 7759084034214778247971576391622212819698022595645523396512935197912507358947265448712319297758956167980413584201946964377785729435826543564472042208999827
  crt coefficient:  4074873801299390551066760636369955957669465077600980966897569652009774826505084817566977483734221289258517186275849939327186461536804759994864093579045356
B的公钥:Sun RSA public key, 1024 bits
  modulus: 102539187515284730067999644651029605499155012515018193956264041032712042245940835316344273183723893202553260620259419073173666324899506874839042020529427319710557325844173671303708388890745691502555168128969439923835578562447745704520780863763243855014463806372707187192860875656087947756935417785902707236111
  public exponent: 65537
B的私钥:Sun RSA private CRT key, 1024 bits
  modulus:          102539187515284730067999644651029605499155012515018193956264041032712042245940835316344273183723893202553260620259419073173666324899506874839042020529427319710557325844173671303708388890745691502555168128969439923835578562447745704520780863763243855014463806372707187192860875656087947756935417785902707236111
  public exponent:  65537
  private exponent: 60911441005196298675210860520152487475587893742804420539715204868158635834364140252080487347842514705717396115283266611802859509813734259187310143906970630220845991871368219715775743370250594182491008406793730989043642353446311784524222989887596013598331427135510011783066371889013758659686178307766978183449
  prime p:          10952081096215932838370494255560322806855249435195895093365419505271086940019997647808658906999895561701787208823891331735140003545850379556296491139129413
  prime q:          9362529971651978753471787637908879302644842060847691470500031927265884682918029490403020820378706946420421723488722740493564033473307756625205829732314947
  prime exponent p: 2815686015382795251441238654682635442157927548310353486246150315765331703501791970458337945344480832493300161458012192325028211845889086243557678551096197
  prime exponent q: 7759084034214778247971576391622212819698022595645523396512935197912507358947265448712319297758956167980413584201946964377785729435826543564472042208999827
  crt coefficient:  4074873801299390551066760636369955957669465077600980966897569652009774826505084817566977483734221289258517186275849939327186461536804759994864093579045356
加密结果:[112, 15, 49, -69, -36, -19, -88, -105, 21, -64, -43, 114, 47, 127, -63, 114, 35, 110, 25, 18, 17, 52, 69, -104, 109, 38, 12, -99, 37, 69, 63, 28, -123, -71, 82, -63, 30, -46, -82, 80, 78, 2, 94, -29, -23, -69, 94, -125, 109, 125, -68, -14, -114, -112, 7, 113, 71, 121, -11, -27, -105, 79, -99, 26, 56, 87, -8, 52, 73, -18, -59, -54, 85, 57, 6, 26, -74, 72, -14, 61, 4, 49, -115, 91, 43, -81, -105, 7, 126, -99, -65, 73, 66, 15, 43, -23, 113, 66, -56, -15, 73, 13, 46, -61, -125, -21, 16, -72, 38, -46, 33, 51, 72, 122, 12, -63, 86, -41, 112, -48, 28, 21, 29, 30, 19, -8, 124, 78]
解密结果:[112, 97, 115, 115, 119, 111, 114, 100]
原文比较:true
验证签名结果:true

 四、信息摘要

在三中并不是对原文进行签名而是对原文的哈希值进行签名,为什么呢?

1、无论输入的消息有多长,计算出来的消息摘要的长度总是固定的。例如应用MD5算法摘要的消息有128个比特位,用SHA-1算法摘要的消息最终有160比特位的输出,SHA-1的变体可以产生192比特位和256比特位的消息摘要。一般认为,摘要的最终输出越长,该摘要算法就越安全。这样就避免了原文过长签名的效率问题

2、消息摘要看起来是“随机的”。这些比特看上去是胡乱的杂凑在一起的。可以用大量的输入来检验其输出是否相同,一般,不同的输入会有不同的输出,而且输出的摘要消息可以通过随机性检验。但是,一个摘要并不是真正随机的,因为用相同的算法对相同的消息求两次摘要,其结果必然相同;而若是真正随机的,则无论如何都是无法重现的。因此消息摘要是“伪随机的”。

3、一般地,只要输入的消息不同,对其进行摘要以后产生的摘要消息也必不相同;但相同的输入必会产生相同的输出。这正是好的消息摘要算法所具有的性质:输入改变了,输出也就改变了;两条相似的消息的摘要确不相近,甚至会大相径庭

4、消息摘要函数是无陷门的单向函数,即只能进行正向的信息摘要,而无法从摘要中恢复出任何的消息,甚至根本就找不到任何与原信息相关的信息。当然,可以采用 强力攻击的方法,即尝试每一个可能的信息,计算其摘要,看看是否与已有的摘要相同,如果这样做,最终肯定会恢复出摘要的消息。但实际上,要得到的信息可能 是无穷 个消息之一,所以这种强力攻击几乎是无效的。

5、好的摘要算法,没有人能从中找到“碰撞”,虽然“碰撞”是肯定存在的。即对于给定的一个摘要,不可能找到一条信息使其摘要正好是给定的。或者说,无法找到两条消息,是它们的摘要相同

 

常见的信息摘要算法SHA1、MD5(已破解、慎用)

byte[] plain = "password".getBytes();
		MessageDigest digest = MessageDigest.getInstance("MD5");
		digest.update(plain);
		byte[] result1 = digest.digest();
		
		plain = "possword".getBytes();
		digest.reset();
		digest.update(plain);
		byte[] result2 = digest.digest();
		
		System.out.println(Arrays.toString(result1));
		System.out.println(Arrays.toString(result2));

 输出结果:

[95, 77, -52, 59, 90, -89, 101, -42, 29, -125, 39, -34, -72, -126, -49, -103]
[112, 68, -103, 81, 72, -7, 93, 85, 65, -122, 71, -65, -74, 95, -89, -93]

 五、一种更为安全的加密方式

在三中A的密钥对进行了加密和解密,B的密钥对进行了签名和验证签名,这样会造成一种情况,当A的密钥对被C截取,C就可以得到B的发送过来的信息,这时就需要在B在给A发信息时再产生一个密钥对,用A的公钥对这个会话密钥进行加密,当A得到时在用A的私钥解密,但是这时签名只是用B的,二A的密钥对只负责解密开会话密钥即可

// B给A发送的信息
		byte[] plain = "password".getBytes();
		System.out.println("原文:" + Arrays.toString(plain));

		KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
		generator.initialize(1024);

		// A生成一个密钥对
		KeyPair aKeyPair = generator.generateKeyPair();
		// A把公钥公开
		PublicKey aPublicKey = aKeyPair.getPublic();
		// A自己保存好私钥
		PrivateKey aPrivateKey = aKeyPair.getPrivate();
		System.out.println("A的公钥:" + aPublicKey);
		System.out.println("A的私钥:" + aPrivateKey);

		// B产生的会话密钥(对称的)
		KeyGenerator generator2 = KeyGenerator.getInstance("AES");
		SecretKey secretKey = generator2.generateKey();
		System.out.println("B的会话密钥:"+Arrays.toString(secretKey.getEncoded()));
		
		// B生成的一个密钥对
		KeyPair bKeyPair = generator.generateKeyPair();
		// B的公钥
		PublicKey bPublicKey = bKeyPair.getPublic();
		// B的私钥
		PrivateKey bPrivateKey = bKeyPair.getPrivate();
		System.out.println("B的公钥:" + aPublicKey);
		System.out.println("B的私钥:" + aPrivateKey);

		// 第一步B操作
		// 用B的会话密钥加密信息
		Cipher cipher = Cipher.getInstance("AES");
		cipher.init(Cipher.ENCRYPT_MODE, secretKey);
		cipher.update(plain);
		byte[] result1 = cipher.doFinal();
		System.out.println("加密结果:" + Arrays.toString(result1));

		// 用A的公钥对B的会话密钥secretKey进行加密
		Cipher rsaCipher = Cipher.getInstance("RSA");
		rsaCipher.init(Cipher.ENCRYPT_MODE, aPublicKey);
		rsaCipher.update(secretKey.getEncoded());
		byte[] sessionKeyEnc = rsaCipher.doFinal();
		System.out.println("加密B会话密钥:" + Arrays.toString(sessionKeyEnc));

		// 把原文做一个信息摘要
		MessageDigest digest = MessageDigest.getInstance("SHA1");
		digest.update(plain);
		byte[] hash = digest.digest();

		// 签名
		Signature signature = Signature.getInstance("SHA1withRSA");
		// B用自己的私钥对信息签名
		signature.initSign(bPrivateKey);
		signature.update(hash);
		byte[] signByte = signature.sign();

		// B把签名结果signByte和加密结果result1一起发送给A

		// 第二步A操作
		// A得到B发过来的会话密钥的加密结果用自己的私钥进行解密,加密会话密钥
		rsaCipher.init(Cipher.DECRYPT_MODE, aPrivateKey);
		rsaCipher.update(sessionKeyEnc);
		byte[] sessionKeyDec = rsaCipher.doFinal();

		SecretKey secretKey2 = new AESKey(secretKey.getAlgorithm(),
				secretKey.getFormat(), sessionKeyDec);
		System.out.println("解密B会话密钥:"+Arrays.toString(secretKey2.getEncoded()));
		// 用会话密钥解密加密信息
		cipher.init(Cipher.DECRYPT_MODE, secretKey2);
		cipher.update(result1);
		byte[] result2 = cipher.doFinal();

		System.out.println("解密结果:" + Arrays.toString(result2));
		System.out.println("原文比较:" + Arrays.equals(result2, plain));

		// 把解密的结果进行信息摘要
		digest.reset();
		digest.update(result2);
		byte[] hash2 = digest.digest();

		// 比较两次摘要的结果是否一致
		signature.initVerify(bPublicKey);
		signature.update(hash2);
		boolean b = signature.verify(signByte);
		System.out.println("验证签名结果:" + b);

 附AESKey的实现

class AESKey implements SecretKey {

	private String alg;
	private String format;
	private byte[] encode;

	public AESKey(String alg, String format, byte[] encode) {
		this.alg = alg;
		this.format = format;
		this.encode = encode;
	}

	@Override
	public String getAlgorithm() {
		return alg;
	}

	@Override
	public String getFormat() {
		return format;
	}

	@Override
	public byte[] getEncoded() {
		return encode;
	}

}

输出结果:

原文:[112, 97, 115, 115, 119, 111, 114, 100]
A的公钥:Sun RSA public key, 1024 bits
  modulus: 91418327984526516476749547644261586889316522330588032287624662687056483794446619299917106424382328807604185610341520333805651808184020229732304326816785271283309582321041169498456578545227365985190079275013558202192417643073047723942028309192889848604991039624232965615569082893809043335310769221406950339451
  public exponent: 65537
A的私钥:Sun RSA private CRT key, 1024 bits
  modulus:          91418327984526516476749547644261586889316522330588032287624662687056483794446619299917106424382328807604185610341520333805651808184020229732304326816785271283309582321041169498456578545227365985190079275013558202192417643073047723942028309192889848604991039624232965615569082893809043335310769221406950339451
  public exponent:  65537
  private exponent: 7289808536355578911263761478079726766308621781583732193037924946252608210778308931769333325813236039924614706191079623181841346866192985955735270334994273822168635554800311834689396926056907915364013116653956729820217943675826705803145502968360556473671192256873645980914820857616540140359605487380347500065
  prime p:          12811208585041226420003104891009334655869873900957079721177285397537909001175110616098948196872226637578122241767087202556901912670110934326807694215062339
  prime q:          7135808255535660896317005149774126239765294875672287001548016927610965298975501762989418545676413755503802272840960204525504790519573640226411713915125609
  prime exponent p: 12100441317463981516160523000112437623525658244093324256841099583334514931744518703131681223348455087854545445895058744304359145157583303260199934077033947
  prime exponent q: 3332555400417778858561950907413166330782556117303228531308728719706254709641014731522912758098753312094006075420651982542870822946314149357001134134919961
  crt coefficient:  4165767192593562897090598706799474220098321601896273854027284136853238852079123306614545261899611295589143417080338467864171030026514316189741786135891848
B的会话密钥:[-95, -12, -94, -23, 115, 101, -29, -48, 111, -63, -39, 29, -25, 17, 50, 76]
B的公钥:Sun RSA public key, 1024 bits
  modulus: 91418327984526516476749547644261586889316522330588032287624662687056483794446619299917106424382328807604185610341520333805651808184020229732304326816785271283309582321041169498456578545227365985190079275013558202192417643073047723942028309192889848604991039624232965615569082893809043335310769221406950339451
  public exponent: 65537
B的私钥:Sun RSA private CRT key, 1024 bits
  modulus:          91418327984526516476749547644261586889316522330588032287624662687056483794446619299917106424382328807604185610341520333805651808184020229732304326816785271283309582321041169498456578545227365985190079275013558202192417643073047723942028309192889848604991039624232965615569082893809043335310769221406950339451
  public exponent:  65537
  private exponent: 7289808536355578911263761478079726766308621781583732193037924946252608210778308931769333325813236039924614706191079623181841346866192985955735270334994273822168635554800311834689396926056907915364013116653956729820217943675826705803145502968360556473671192256873645980914820857616540140359605487380347500065
  prime p:          12811208585041226420003104891009334655869873900957079721177285397537909001175110616098948196872226637578122241767087202556901912670110934326807694215062339
  prime q:          7135808255535660896317005149774126239765294875672287001548016927610965298975501762989418545676413755503802272840960204525504790519573640226411713915125609
  prime exponent p: 12100441317463981516160523000112437623525658244093324256841099583334514931744518703131681223348455087854545445895058744304359145157583303260199934077033947
  prime exponent q: 3332555400417778858561950907413166330782556117303228531308728719706254709641014731522912758098753312094006075420651982542870822946314149357001134134919961
  crt coefficient:  4165767192593562897090598706799474220098321601896273854027284136853238852079123306614545261899611295589143417080338467864171030026514316189741786135891848
加密结果:[-109, 14, -118, 18, 40, 66, 3, 94, 41, 110, 0, -47, 78, -91, 122, 111]
加密B会话密钥:[125, 88, -125, 31, -106, 119, -82, -119, -79, 23, -113, 84, 28, -33, 86, -48, 80, 10, 45, 4, 98, -55, 81, 112, -58, -126, -117, 21, -9, 88, 24, -121, -36, -124, 44, 7, -112, 107, -49, -56, -82, 56, 2, -15, -49, -32, -53, 99, 104, 21, -46, -86, -101, -79, -121, 102, -100, 64, -28, -85, -9, -87, 12, -80, -123, -59, 24, -118, 114, -64, 110, -47, -25, -97, 1, 26, -45, 34, -119, -30, 85, 34, 117, 105, -83, -97, 107, -24, 37, 110, -43, 92, -34, 108, 79, -17, 64, -64, 76, 90, 95, -77, 39, -31, 16, -102, -83, 3, -125, -110, 104, 59, -69, 119, -128, 44, 96, -50, 34, 109, -26, -36, 126, -120, 127, -106, -126, 50]
解密B会话密钥:[-95, -12, -94, -23, 115, 101, -29, -48, 111, -63, -39, 29, -25, 17, 50, 76]
解密结果:[112, 97, 115, 115, 119, 111, 114, 100]
原文比较:true
验证签名结果:true
 

六、这样就安全了吗?----------数字证书的产生

当B获取A的公钥时,B怎么确定这就是A的公钥?唯一的方法就是B不仅拿到A的公钥、还要拿到A的个人信息,相等于身份证,这时X509Certificate就产生了,对于X509证书的组装现在比较好的实现非bouncycastle莫属了

1、数字证书的组装

 

public static X509Certificate getCertificate(PublicKey publicKey,
			X500Name subject) throws Exception {
		
		//公钥算法OID
		String sAlg = null;
		//TODO 仅对RSA
		sAlg = X509Util.getAlgorithmOID("SHA1with"+publicKey.getAlgorithm()).toString();
		byte[] publicKeyEncode = publicKey.getEncoded();
		
		//组装公钥信息
		SubjectPublicKeyInfo publicKeyInfo;
		if (sAlg.equals("1.2.156.197.1.301")) {
			publicKeyInfo = new SubjectPublicKeyInfo(new AlgorithmIdentifier(
					sAlg), publicKeyEncode);
		} else {
			publicKeyInfo = new SubjectPublicKeyInfo(
					ASN1Sequence.getInstance(publicKeyEncode));
		}
		
		//颁发者
		X500Name issuer;
		issuer = subject;
		MessageDigest md = null;
		try {
			md = MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		//证书序列号
		BigInteger serial = new BigInteger(md.digest(publicKeyEncode));
		//证书生效日期
		Date notBefore = new Date();
		long year = 365 * 24 * 60 * 60 * 1000;
		//证书结束日期
		Date notAfter = new Date(notBefore.getTime() + 10 * year);
		//组装证书
		X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder(
				issuer, serial, notBefore, notAfter, subject, publicKeyInfo);
		
		//证书签名
		ContentSigner signer = new ContentSigner() {

			//TODO 签名为空
			public byte[] getSignature() {
				return new byte[0];
			}

			public OutputStream getOutputStream() {
				return new ByteArrayOutputStream();
			}

			public AlgorithmIdentifier getAlgorithmIdentifier() {
				return new AlgorithmIdentifier(X509Util.getAlgorithmOID(
						"SHA1withRSA").toString());
			}
		};
		X509CertificateHolder certHolder = certBuilder.build(signer);
		byte[] certBuf = null;
		try {
			certBuf = certHolder.getEncoded();
		} catch (IOException e) {
			e.printStackTrace();
		}
		CertificateFactory cf = CertificateFactory.getInstance("X509");
		return (X509Certificate) cf
				.generateCertificate(new ByteArrayInputStream(certBuf));
	}
 

2、用数字证书代替公钥,不仅验证公钥,也要验证证书的有效性

KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
		generator.initialize(1024);

		// A生成一个密钥对
		KeyPair aKeyPair = generator.generateKeyPair();
		// A把公钥公开
		PublicKey aPublicKey = aKeyPair.getPublic();
		// A自己保存好私钥
		PrivateKey aPrivateKey = aKeyPair.getPrivate();
		System.out.println("A的公钥:" + aPublicKey);
		System.out.println("A的私钥:" + aPrivateKey);
		
		X500Name subject = new X500Name("o=ChinaZF,ou=特工,cn=007");
		
		X509Certificate certificate = getCertificate(aPublicKey, subject);
		System.out.println(certificate);
		
		//没有签名,签名是无效的。
		//certificate.verify(aPublicKey);

 输出结果:

A的公钥:Sun RSA public key, 1024 bits
  modulus: 121375921797136310584113277075626417702106134650309911734631920262170928928191143305688909496584272517313783965325179965007347203684990245350583963403130438989877867943122025651419267585781869015209835513328257718652754130646803812568871376045617234858685855024104612111317545237059745480540648495825269928597
  public exponent: 65537
A的私钥:Sun RSA private CRT key, 1024 bits
  modulus:          121375921797136310584113277075626417702106134650309911734631920262170928928191143305688909496584272517313783965325179965007347203684990245350583963403130438989877867943122025651419267585781869015209835513328257718652754130646803812568871376045617234858685855024104612111317545237059745480540648495825269928597
  public exponent:  65537
  private exponent: 93254829947223776597065105827075041740606835803394341907226773898120035770956995878226859024390922289154232937211327750400765273771309547646946828650042355995573887546324363837040512754119171427890650604483145044299112375628241658963865665079757096855204500705764805660706159297347368063382327902394539344193
  prime p:          11158242331654507984390217603269741420760310208724980668108807848920513940485092997460488756039704124521900603405927494488714645375960645043236583812293637
  prime q:          10877691861271763807257505279108273122815111142116808418621656894013946974232416694440801989770282169671002997798867760467165866508205378344644397636512081
  prime exponent p: 8325308353040910194557469221427343576793836284636680115189656014106768553059189120494117509083867926222925915213437335024629884333944544628594266982827017
  prime exponent q: 2552075774889217393234224959512470933005861557916719505694899009755686843703520745437260957851410022443220502832833219173034199969943175571467297222317313
  crt coefficient:  7894234470957278080153194562540672330990888843195530292196598522531445521952494004124571924854822356789631822756291673583770445705652331919704012044777045
[
[
  Version: V3
  Subject: CN=007, OU=特工, O=ChinaZF
  Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5

  Key:  Sun RSA public key, 1024 bits
  modulus: 121375921797136310584113277075626417702106134650309911734631920262170928928191143305688909496584272517313783965325179965007347203684990245350583963403130438989877867943122025651419267585781869015209835513328257718652754130646803812568871376045617234858685855024104612111317545237059745480540648495825269928597
  public exponent: 65537
  Validity: [From: Fri Dec 23 17:44:24 CST 2011,
               To: Mon Jun 11 00:29:13 CST 2012]
  Issuer: CN=007, OU=特工, O=ChinaZF
  SerialNumber: [    37ce978c 070962d7 6d10a4bf df2ea726]

]
  Algorithm: [SHA1withRSA]
  Signature:

]

这里面的证书可以base64的格式保存到文件中,在windows下用cer格式,就可以看到!

3、后面的和三一样

七、我也可颁发证书,是每个人都可以?-----CA的必要性

假设六中我的签名是有效的,验证签名肯定可以通过,但是每个人都以颁发证书,这不乱套了,怎么办?想你的身份证是谁颁发的?对,CA需要国家的认证,需要国家的信任你,所以CA中心就产生了。。。。

八、以后有空在写

1、加解密算法都是规定好的,可不可一自己写

2、估计都听过加密机,JCE可以实现连接加密机吗?可以连接智能卡吗?

3、证书的有效性,CRL

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

 

 

4
0
分享到:
评论
4 楼 沙舟狼客 2012-10-05  
ggd543 写道
第五部分 有点多此一举,SSH会话过程不是这样的

这里只是原理部分
3 楼 沙舟狼客 2012-10-05  
ggd543 写道
第六部分能否提供 X509CertificateHolder , X509v3CertificateBuilder,ContentSigner,ASN1Sequence,SubjectPublicKeyInfo,X509Util的实现?

这个你可以看一下bouncycastle
2 楼 ggd543 2012-10-04  
第六部分能否提供 X509CertificateHolder , X509v3CertificateBuilder,ContentSigner,ASN1Sequence,SubjectPublicKeyInfo,X509Util的实现?
1 楼 ggd543 2012-10-04  
第五部分 有点多此一举,SSH会话过程不是这样的

相关推荐

    bcmail-jdk14-138.jar

    此外,bcmail-jdk14-138.jar也提供了处理S/MIME协议的APIs,可以和JCE/JCA提供者如Bouncy Castle Cryptography APIs一同使用。 在使用该API时,还需要配合JavaMail API和Java激活框架。值得注意的是,如果在程序中...

    AES CBC加解密源代码

    AES(Advanced Encryption Standard)是一种广泛使用的块加密标准,它的全称是高级加密标准。AES的加密过程基于替换和置换操作,具有很高的安全性和效率。它提供了128位、192位和256位的密钥长度,分别对应不同的...

    Java加密/解密技术

    JCE提供了各种加密算法的实现,而JCA则是一套框架,用于支持各种加密服务。 8. **加密工具类** Java的`java.security`和`javax.crypto`包中包含了许多用于加密操作的工具类,如Cipher用于加解密操作,...

    Java实现对文档的加密解密

    2. **Java Cryptography Extension (JCE)**:JCE是JCA的扩展,主要处理高级加密标准(AES)、RSA、椭圆曲线加密(ECC)等更强大的加密算法。在Java中,默认的JCE有加密强度的限制,但可以通过安装不受限制的JCE政策...

    jce_policy-1_4_2

    9. **安全性更新**:随着密码学的发展,JCE会定期更新以包含最新的加密标准和安全补丁,因此保持JCE的版本更新是保证系统安全的重要措施。 10. **跨平台兼容**:作为Java的一部分,JCE具有跨平台的特性,可以在任何...

    java做的文件加密及解密软件

    JCA是Java平台的基础框架,用于处理加密、签名和消息认证码等任务,而JCE是JCA的一部分,专门用于实现高级加密算法。开发者可以利用这些API创建安全的加密程序,确保数据在传输和存储过程中的安全性。 GUI设计在...

    利用DES加密算法保护Java源代码

    JCE是JCA的一部分,专注于加密功能,如数字签名和信息摘要。Java环境通常包含一个默认的密码服务提供者,如Sun的提供者,但用户也可以添加自定义的提供者以支持特定的加密算法。 使用DES加密Java源代码的步骤大致...

    Java加密与解密的艺术PDF和源码

    2. **Java加密API**:详细介绍JCE和JCA提供的各种类和接口,如何导入和配置不受限制的加密策略文件,以便使用更强的加密强度。 3. **加密算法实现**:通过实例展示如何使用Java实现各种加密算法,包括对称加密的AES...

    java源码:Java加密库 JSDSI.rar

    在Java中,加密技术主要依赖于Java Cryptography Extension (JCE)框架,它提供了大量的接口和类来支持加密算法。JSDSI(Java Security and Distributed Systems Interface)可能是基于JCE进行扩展或封装的一个库,以...

    java加密与解密的艺术全包括源码.rar

    JCA是Java加密架构,负责提供加密服务的接口和抽象,而JCE是Java加密扩展,提供了具体实现,支持各种加密算法。 8. **证书与证书链**:在数字证书中,证书权威机构(CA)使用其私钥为用户或服务器签发证书,包含了...

    Java加密与解密的艺术含源码高清非扫描

    5. 加密API的使用:如何在Java代码中集成JCA和JCE,进行加密和解密操作。 6. 密码学的最佳实践:避免常见的加密错误,如弱密钥、明文传输等。 7. 源码分析:提供实际的加密和解密代码示例,帮助读者加深理解。 通过...

    Java加密算法(源代码)

    4. **Java加密API(JCA)与Java加密扩展(JCE)**: Java提供了一套完整的加密API,即Java Cryptography Architecture (JCA),它定义了用于加密、解密、签名和消息认证码的操作。JCE(Java Cryptography Extension...

    java网上聊天加密系统源代码

    JCA提供了一组API来处理各种加密操作,而JCE则提供了更强的加密算法支持,包括AES和RSA。 此外,Socket编程是实现客户端和服务端通信的关键。Java的Socket类提供了网络通信的基本功能,允许两台机器之间建立连接并...

    一种改进加密Java源码的方法.pdf

    JCE是JCA(Java Cryptography Architecture)的扩展。JCE没有规定具体的加密算法,但提供了一个框架, 加密算法的具体实现可以作为服务提供者加入。除了JCE框架之外,JCE软件包还包含了SunJCE服务提供者,其中包括...

    java加密与解密

    - **Java Cryptography Extension (JCE)**: JCE是JCA的一部分,提供了高级加密标准(AES)、RSA、DSA等强加密算法的支持。JCE不受默认的出口限制,允许开发者实现更强大的加密功能。 2. **对称加密** - **常见的...

    JAVA数据加密方面的资料

    JCA是基础框架,提供各种加密服务,而JCE则提供了更强的加密算法支持,包括不限强度的加密。在Java中,我们通常通过`java.security.Key`、`javax.crypto.Cipher`和`java.security.AlgorithmParameters`等接口和类来...

    pc1-128-java.zip_Java加密_java 加密_pc1_pc1 java

    JCA是核心框架,定义了加密操作的接口,而JCE是JCA的扩展,提供了具体的加密算法实现。 1. **加密算法**: - **对称加密**:如AES(高级加密标准),是广泛使用的128位块密码,支持128、192和256位密钥长度。AES因...

    java加密文件

    在Java中,我们可以利用内置的Java Cryptography Architecture (JCA) 和 Java Cryptography Extension (JCE) 来实现文件的加密和解密。下面我们将深入探讨如何通过Java代码来对本地文件进行加密。 1. **Java ...

    format-preserving-encryption-java-master.zip_formesz_gettingzqq_

    对于FF1保形加密,我们可以利用Java的加密库,如Java Cryptography Architecture (JCA) 和 Java Cryptography Extension (JCE),来实现这一功能。 1. **Java Cryptography Architecture (JCA) 和 Java Cryptography...

Global site tag (gtag.js) - Google Analytics