Java加密技术(七)——非对称加密算法最高级ECC

本文介绍如何在Java中实现椭圆曲线密码编码学(ECC),包括密钥生成、公钥加密及私钥解密等核心过程,并提供了一段示例代码。值得注意的是,Java标准库直接支持ECC算法有限,需借助特定实现。

ECC

ECC-Elliptic Curves Cryptography,椭圆曲线密码编码学,是目前已知的公钥体制中,对每比特所提供加密强度最高的一种体制。在软件注册保护方面起到很大的作用,一般的序列号通常由该算法产生。
当我开始整理《Java加密技术(二)》的时候,我就已经在开始研究ECC了,但是关于Java实现ECC算法的资料实在是太少了,无论是国内还是国外的资料,无论是官方还是非官方的解释,最终只有一种答案——ECC算法在jdk1.5后加入支持,目前仅仅只能完成密钥的生成与解析。 如果想要获得ECC算法实现,需要调用硬件完成加密/解密(ECC算法相当耗费资源,如果单纯使用CPU进行加密/解密,效率低下),涉及到Java Card领域,PKCS#11。 其实,PKCS#11配置很简单,但缺乏硬件设备,无法尝试!

尽管如此,我照旧提供相应的Java实现代码,以供大家参考。

通过java代码实现如下: Coder类见Java加密技术(一)
Java代码 收藏代码
  1. importjava.math.BigInteger;
  2. importjava.security.Key;
  3. importjava.security.KeyFactory;
  4. importjava.security.interfaces.ECPrivateKey;
  5. importjava.security.interfaces.ECPublicKey;
  6. importjava.security.spec.ECFieldF2m;
  7. importjava.security.spec.ECParameterSpec;
  8. importjava.security.spec.ECPoint;
  9. importjava.security.spec.ECPrivateKeySpec;
  10. importjava.security.spec.ECPublicKeySpec;
  11. importjava.security.spec.EllipticCurve;
  12. importjava.security.spec.PKCS8EncodedKeySpec;
  13. importjava.security.spec.X509EncodedKeySpec;
  14. importjava.util.HashMap;
  15. importjava.util.Map;
  16. importjavax.crypto.Cipher;
  17. importjavax.crypto.NullCipher;
  18. importsun.security.ec.ECKeyFactory;
  19. importsun.security.ec.ECPrivateKeyImpl;
  20. importsun.security.ec.ECPublicKeyImpl;
  21. /**
  22. *ECC安全编码组件
  23. *
  24. *@author梁栋
  25. *@version1.0
  26. *@since1.0
  27. */
  28. publicabstractclassECCCoderextendsCoder{
  29. publicstaticfinalStringALGORITHM="EC";
  30. privatestaticfinalStringPUBLIC_KEY="ECCPublicKey";
  31. privatestaticfinalStringPRIVATE_KEY="ECCPrivateKey";
  32. /**
  33. *解密<br>
  34. *用私钥解密
  35. *
  36. *@paramdata
  37. *@paramkey
  38. *@return
  39. *@throwsException
  40. */
  41. publicstaticbyte[]decrypt(byte[]data,Stringkey)throwsException{
  42. //对密钥解密
  43. byte[]keyBytes=decryptBASE64(key);
  44. //取得私钥
  45. PKCS8EncodedKeySpecpkcs8KeySpec=newPKCS8EncodedKeySpec(keyBytes);
  46. KeyFactorykeyFactory=ECKeyFactory.INSTANCE;
  47. ECPrivateKeypriKey=(ECPrivateKey)keyFactory
  48. .generatePrivate(pkcs8KeySpec);
  49. ECPrivateKeySpececPrivateKeySpec=newECPrivateKeySpec(priKey.getS(),
  50. priKey.getParams());
  51. //对数据解密
  52. //TODOChipher不支持EC算法未能实现
  53. Ciphercipher=newNullCipher();
  54. //Cipher.getInstance(ALGORITHM,keyFactory.getProvider());
  55. cipher.init(Cipher.DECRYPT_MODE,priKey,ecPrivateKeySpec.getParams());
  56. returncipher.doFinal(data);
  57. }
  58. /**
  59. *加密<br>
  60. *用公钥加密
  61. *
  62. *@paramdata
  63. *@paramprivateKey
  64. *@return
  65. *@throwsException
  66. */
  67. publicstaticbyte[]encrypt(byte[]data,StringprivateKey)
  68. throwsException{
  69. //对公钥解密
  70. byte[]keyBytes=decryptBASE64(privateKey);
  71. //取得公钥
  72. X509EncodedKeySpecx509KeySpec=newX509EncodedKeySpec(keyBytes);
  73. KeyFactorykeyFactory=ECKeyFactory.INSTANCE;
  74. ECPublicKeypubKey=(ECPublicKey)keyFactory
  75. .generatePublic(x509KeySpec);
  76. ECPublicKeySpececPublicKeySpec=newECPublicKeySpec(pubKey.getW(),
  77. pubKey.getParams());
  78. //对数据加密
  79. //TODOChipher不支持EC算法未能实现
  80. Ciphercipher=newNullCipher();
  81. //Cipher.getInstance(ALGORITHM,keyFactory.getProvider());
  82. cipher.init(Cipher.ENCRYPT_MODE,pubKey,ecPublicKeySpec.getParams());
  83. returncipher.doFinal(data);
  84. }
  85. /**
  86. *取得私钥
  87. *
  88. *@paramkeyMap
  89. *@return
  90. *@throwsException
  91. */
  92. publicstaticStringgetPrivateKey(Map<String,Object>keyMap)
  93. throwsException{
  94. Keykey=(Key)keyMap.get(PRIVATE_KEY);
  95. returnencryptBASE64(key.getEncoded());
  96. }
  97. /**
  98. *取得公钥
  99. *
  100. *@paramkeyMap
  101. *@return
  102. *@throwsException
  103. */
  104. publicstaticStringgetPublicKey(Map<String,Object>keyMap)
  105. throwsException{
  106. Keykey=(Key)keyMap.get(PUBLIC_KEY);
  107. returnencryptBASE64(key.getEncoded());
  108. }
  109. /**
  110. *初始化密钥
  111. *
  112. *@return
  113. *@throwsException
  114. */
  115. publicstaticMap<String,Object>initKey()throwsException{
  116. BigIntegerx1=newBigInteger(
  117. "2fe13c0537bbc11acaa07d793de4e6d5e5c94eee8",16);
  118. BigIntegerx2=newBigInteger(
  119. "289070fb05d38ff58321f2e800536d538ccdaa3d9",16);
  120. ECPointg=newECPoint(x1,x2);
  121. //theorderofgenerator
  122. BigIntegern=newBigInteger(
  123. "5846006549323611672814741753598448348329118574063",10);
  124. //thecofactor
  125. inth=2;
  126. intm=163;
  127. int[]ks={7,6,3};
  128. ECFieldF2mecField=newECFieldF2m(m,ks);
  129. //y^2+xy=x^3+x^2+1
  130. BigIntegera=newBigInteger("1",2);
  131. BigIntegerb=newBigInteger("1",2);
  132. EllipticCurveellipticCurve=newEllipticCurve(ecField,a,b);
  133. ECParameterSpececParameterSpec=newECParameterSpec(ellipticCurve,g,
  134. n,h);
  135. //公钥
  136. ECPublicKeypublicKey=newECPublicKeyImpl(g,ecParameterSpec);
  137. BigIntegers=newBigInteger(
  138. "1234006549323611672814741753598448348329118574063",10);
  139. //私钥
  140. ECPrivateKeyprivateKey=newECPrivateKeyImpl(s,ecParameterSpec);
  141. Map<String,Object>keyMap=newHashMap<String,Object>(2);
  142. keyMap.put(PUBLIC_KEY,publicKey);
  143. keyMap.put(PRIVATE_KEY,privateKey);
  144. returnkeyMap;
  145. }
  146. }


请注意上述代码中的 TODO内容,再次提醒注意, Chipher不支持EC算法,以上代码仅供参考。 Chipher、Signature、KeyPairGenerator、KeyAgreement、SecretKey均不支持EC算法。为了确保程序能够正常执行,我们使用了NullCipher类,验证程序。

照旧提供一个测试类:
Java代码 收藏代码
  1. importstaticorg.junit.Assert.*;
  2. importjava.math.BigInteger;
  3. importjava.security.spec.ECFieldF2m;
  4. importjava.security.spec.ECParameterSpec;
  5. importjava.security.spec.ECPoint;
  6. importjava.security.spec.ECPrivateKeySpec;
  7. importjava.security.spec.ECPublicKeySpec;
  8. importjava.security.spec.EllipticCurve;
  9. importjava.util.Map;
  10. importorg.junit.Test;
  11. /**
  12. *
  13. *@author梁栋
  14. *@version1.0
  15. *@since1.0
  16. */
  17. publicclassECCCoderTest{
  18. @Test
  19. publicvoidtest()throwsException{
  20. StringinputStr="abc";
  21. byte[]data=inputStr.getBytes();
  22. Map<String,Object>keyMap=ECCCoder.initKey();
  23. StringpublicKey=ECCCoder.getPublicKey(keyMap);
  24. StringprivateKey=ECCCoder.getPrivateKey(keyMap);
  25. System.err.println("公钥:\n"+publicKey);
  26. System.err.println("私钥:\n"+privateKey);
  27. byte[]encodedData=ECCCoder.encrypt(data,publicKey);
  28. byte[]decodedData=ECCCoder.decrypt(encodedData,privateKey);
  29. StringoutputStr=newString(decodedData);
  30. System.err.println("加密前:"+inputStr+"\n\r"+"解密后:"+outputStr);
  31. assertEquals(inputStr,outputStr);
  32. }
  33. }


控制台输出:
Console代码 收藏代码
  1. 公钥:
  2. MEAwEAYHKoZIzj0CAQYFK4EEAAEDLAAEAv4TwFN7vBGsqgfXk95ObV5clO7oAokHD7BdOP9YMh8u
  3. gAU21TjM2qPZ
  4. 私钥:
  5. MDICAQAwEAYHKoZIzj0CAQYFK4EEAAEEGzAZAgEBBBTYJsR3BN7TFw7JHcAHFkwNmfil7w==
  6. 加密前:abc
  7. 解密后:abc
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值