- 浏览: 161647 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
沙舟狼客:
为了方便使用可以配置到环境变量里面MINGW_HOME=C:\ ...
windows下用mingw32+sdl进行简单2d游戏开发(c语言) -
沙舟狼客:
如果安装autotools时不用gcccc相当于gcc的链接n ...
windows下用mingw32+sdl进行简单2d游戏开发(c语言) -
lirihong:
java中文乱码完全解决方案 ?? 高度很高,深度、全面度全 ...
java中文乱码完全解决方案 -
沙舟狼客:
非常适合想写windows游戏的菜鸟
windows下用mingw32+sdl进行简单2d游戏开发(c语言) -
xixilive:
噢喔~~语义全无
京东导航的jquery实现
一、对称密钥-------最原始的加密解密
对称密钥最好的理解就是:加密和解密用同一个密钥,典型的例子就是凯撒密码,他的基本思想是:通过把字母移动一定的位数来实现加密和解密。例如,如果密匙是把明文字母的位数向后移动三位,那么明文字母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
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
评论
这里只是原理部分
这个你可以看一下bouncycastle
发表评论
-
java中文乱码完全解决方案
2013-11-18 22:05 24291、代码编码全部用UTF8,特别是配置用的属性文件 2、J ... -
Highcharts动态曲线图(使用jna监视cpu使用率)
2012-01-10 22:30 92581、CPU使用率获取,因为我要用JNA调用,所以用c++调用w ... -
grails验证码插件-JCaptcha
2012-01-10 12:56 23711、安装 grails install-plugin jca ... -
jogl入门之简单的贪吃蛇
2012-01-05 13:43 20141、代码: package org.ligson.jo ... -
jogl入门
2011-12-31 13:19 51281、jogl是什么? jogl是Java OpenGL的 ... -
grails学习之自定义标签
2011-12-30 17:22 57821、在grails项目结构中有一个taglib文件夹(项目名/ ... -
开发一个JCE的Provider
2011-12-23 13:42 44831、开发环境ubuntu+eclipse+openJDK ... -
enum还有人记得吗?
2011-12-21 15:42 1115enum其实挺好用的,特别是对于一些固定的东西! packa ... -
JNA入门1
2011-12-06 22:15 37111、jna是什么 jna是java native acces ... -
利用BC替换X509证书的公钥
2011-11-23 09:54 2252public static X509Certificate r ... -
利用BC的X509v3CertificateBuilder组装X509证书
2011-11-22 17:38 3894// 设置开始日期和结束日期 long year = 3 ... -
grails框架中webService插件的使用(axis2,cxf)
2011-09-17 22:40 3220一、cxf插件的使用: 1、运行命令: grails in ... -
Java直接发送邮件或写好的eml邮件
2011-08-03 13:50 1534import java.io.File; import ... -
利用bouncycastle组装X509证书
2011-08-02 19:02 9471CreateCert.java package com.se ... -
Java中对称密钥、非对称密钥和数字签名的用法
2011-04-16 12:21 32111、非对称密钥: package com.mysec; ... -
eclipse3.6 太阳神版 中文汉化插件
2011-04-09 20:00 1153经常用eclipse,但用多了英文版,突然间想找个新鲜感,于是 ... -
Java中的按位取反运算符,哪位能详解一下?
2011-03-14 23:29 2240最近面试遇到了这样一道题: System.out.print ... -
Java常见排序算法
2011-02-24 17:53 857package test; import java ... -
常见模式例子
2011-02-24 17:37 1019工厂模式 package login.sj; ... -
关于Java中各种修饰符与访问修饰符的说明
2011-02-24 15:05 1030类: 访问修饰符 修饰符 class 类名称 exte ...
相关推荐
此外,bcmail-jdk14-138.jar也提供了处理S/MIME协议的APIs,可以和JCE/JCA提供者如Bouncy Castle Cryptography APIs一同使用。 在使用该API时,还需要配合JavaMail API和Java激活框架。值得注意的是,如果在程序中...
AES(Advanced Encryption Standard)是一种广泛使用的块加密标准,它的全称是高级加密标准。AES的加密过程基于替换和置换操作,具有很高的安全性和效率。它提供了128位、192位和256位的密钥长度,分别对应不同的...
JCE提供了各种加密算法的实现,而JCA则是一套框架,用于支持各种加密服务。 8. **加密工具类** Java的`java.security`和`javax.crypto`包中包含了许多用于加密操作的工具类,如Cipher用于加解密操作,...
2. **Java Cryptography Extension (JCE)**:JCE是JCA的扩展,主要处理高级加密标准(AES)、RSA、椭圆曲线加密(ECC)等更强大的加密算法。在Java中,默认的JCE有加密强度的限制,但可以通过安装不受限制的JCE政策...
9. **安全性更新**:随着密码学的发展,JCE会定期更新以包含最新的加密标准和安全补丁,因此保持JCE的版本更新是保证系统安全的重要措施。 10. **跨平台兼容**:作为Java的一部分,JCE具有跨平台的特性,可以在任何...
JCA是Java平台的基础框架,用于处理加密、签名和消息认证码等任务,而JCE是JCA的一部分,专门用于实现高级加密算法。开发者可以利用这些API创建安全的加密程序,确保数据在传输和存储过程中的安全性。 GUI设计在...
JCE是JCA的一部分,专注于加密功能,如数字签名和信息摘要。Java环境通常包含一个默认的密码服务提供者,如Sun的提供者,但用户也可以添加自定义的提供者以支持特定的加密算法。 使用DES加密Java源代码的步骤大致...
2. **Java加密API**:详细介绍JCE和JCA提供的各种类和接口,如何导入和配置不受限制的加密策略文件,以便使用更强的加密强度。 3. **加密算法实现**:通过实例展示如何使用Java实现各种加密算法,包括对称加密的AES...
在Java中,加密技术主要依赖于Java Cryptography Extension (JCE)框架,它提供了大量的接口和类来支持加密算法。JSDSI(Java Security and Distributed Systems Interface)可能是基于JCE进行扩展或封装的一个库,以...
JCA是Java加密架构,负责提供加密服务的接口和抽象,而JCE是Java加密扩展,提供了具体实现,支持各种加密算法。 8. **证书与证书链**:在数字证书中,证书权威机构(CA)使用其私钥为用户或服务器签发证书,包含了...
5. 加密API的使用:如何在Java代码中集成JCA和JCE,进行加密和解密操作。 6. 密码学的最佳实践:避免常见的加密错误,如弱密钥、明文传输等。 7. 源码分析:提供实际的加密和解密代码示例,帮助读者加深理解。 通过...
4. **Java加密API(JCA)与Java加密扩展(JCE)**: Java提供了一套完整的加密API,即Java Cryptography Architecture (JCA),它定义了用于加密、解密、签名和消息认证码的操作。JCE(Java Cryptography Extension...
JCA提供了一组API来处理各种加密操作,而JCE则提供了更强的加密算法支持,包括AES和RSA。 此外,Socket编程是实现客户端和服务端通信的关键。Java的Socket类提供了网络通信的基本功能,允许两台机器之间建立连接并...
JCE是JCA(Java Cryptography Architecture)的扩展。JCE没有规定具体的加密算法,但提供了一个框架, 加密算法的具体实现可以作为服务提供者加入。除了JCE框架之外,JCE软件包还包含了SunJCE服务提供者,其中包括...
- **Java Cryptography Extension (JCE)**: JCE是JCA的一部分,提供了高级加密标准(AES)、RSA、DSA等强加密算法的支持。JCE不受默认的出口限制,允许开发者实现更强大的加密功能。 2. **对称加密** - **常见的...
JCA是基础框架,提供各种加密服务,而JCE则提供了更强的加密算法支持,包括不限强度的加密。在Java中,我们通常通过`java.security.Key`、`javax.crypto.Cipher`和`java.security.AlgorithmParameters`等接口和类来...
JCA是核心框架,定义了加密操作的接口,而JCE是JCA的扩展,提供了具体的加密算法实现。 1. **加密算法**: - **对称加密**:如AES(高级加密标准),是广泛使用的128位块密码,支持128、192和256位密钥长度。AES因...
在Java中,我们可以利用内置的Java Cryptography Architecture (JCA) 和 Java Cryptography Extension (JCE) 来实现文件的加密和解密。下面我们将深入探讨如何通过Java代码来对本地文件进行加密。 1. **Java ...
对于FF1保形加密,我们可以利用Java的加密库,如Java Cryptography Architecture (JCA) 和 Java Cryptography Extension (JCE),来实现这一功能。 1. **Java Cryptography Architecture (JCA) 和 Java Cryptography...