ECC-Elliptic Curves Cryptography,椭圆曲线密码编码学

时间:2023-03-08 22:30:54

ECC
ECC-Elliptic Curves Cryptography,椭圆曲线密码编码学,是目前已知的公钥*中,对每比特所提供加密强度最高的一种*。在软件注册保护方面起到很大的作用,一般的序列号通常由该算法产生。

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



    尽管如此,我照旧提供相应的Java实现代码,以供大家参考。ECC-Elliptic Curves Cryptography,椭圆曲线密码编码学



通过java代码实现如下:Coder类见 Java加密技术(一)

  1. import java.math.BigInteger;
  2. import java.security.Key;
  3. import java.security.KeyFactory;
  4. import java.security.interfaces.ECPrivateKey;
  5. import java.security.interfaces.ECPublicKey;
  6. import java.security.spec.ECFieldF2m;
  7. import java.security.spec.ECParameterSpec;
  8. import java.security.spec.ECPoint;
  9. import java.security.spec.ECPrivateKeySpec;
  10. import java.security.spec.ECPublicKeySpec;
  11. import java.security.spec.EllipticCurve;
  12. import java.security.spec.PKCS8EncodedKeySpec;
  13. import java.security.spec.X509EncodedKeySpec;
  14. import java.util.HashMap;
  15. import java.util.Map;
  16. import javax.crypto.Cipher;
  17. import javax.crypto.NullCipher;
  18. import sun.security.ec.ECKeyFactory;
  19. import sun.security.ec.ECPrivateKeyImpl;
  20. import sun.security.ec.ECPublicKeyImpl;
  21. /**
  22. * ECC安全编码组件
  23. *
  24. * @author 梁栋
  25. * @version 1.0
  26. * @since 1.0
  27. */
  28. public abstract class ECCCoder extends Coder {
  29. public static final String ALGORITHM = "EC";
  30. private static final String PUBLIC_KEY = "ECCPublicKey";
  31. private static final String PRIVATE_KEY = "ECCPrivateKey";
  32. /**
  33. * 解密<br>
  34. * 用私钥解密
  35. *
  36. * @param data
  37. * @param key
  38. * @return
  39. * @throws Exception
  40. */
  41. public static byte[] decrypt(byte[] data, String key) throws Exception {
  42. // 对密钥解密
  43. byte[] keyBytes = decryptBASE64(key);
  44. // 取得私钥
  45. PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
  46. KeyFactory keyFactory = ECKeyFactory.INSTANCE;
  47. ECPrivateKey priKey = (ECPrivateKey) keyFactory
  48. .generatePrivate(pkcs8KeySpec);
  49. ECPrivateKeySpec ecPrivateKeySpec = new ECPrivateKeySpec(priKey.getS(),
  50. priKey.getParams());
  51. // 对数据解密
  52. // TODO Chipher不支持EC算法 未能实现
  53. Cipher cipher = new NullCipher();
  54. // Cipher.getInstance(ALGORITHM, keyFactory.getProvider());
  55. cipher.init(Cipher.DECRYPT_MODE, priKey, ecPrivateKeySpec.getParams());
  56. return cipher.doFinal(data);
  57. }
  58. /**
  59. * 加密<br>
  60. * 用公钥加密
  61. *
  62. * @param data
  63. * @param privateKey
  64. * @return
  65. * @throws Exception
  66. */
  67. public static byte[] encrypt(byte[] data, String privateKey)
  68. throws Exception {
  69. // 对公钥解密
  70. byte[] keyBytes = decryptBASE64(privateKey);
  71. // 取得公钥
  72. X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
  73. KeyFactory keyFactory = ECKeyFactory.INSTANCE;
  74. ECPublicKey pubKey = (ECPublicKey) keyFactory
  75. .generatePublic(x509KeySpec);
  76. ECPublicKeySpec ecPublicKeySpec = new ECPublicKeySpec(pubKey.getW(),
  77. pubKey.getParams());
  78. // 对数据加密
  79. // TODO Chipher不支持EC算法 未能实现
  80. Cipher cipher = new NullCipher();
  81. // Cipher.getInstance(ALGORITHM, keyFactory.getProvider());
  82. cipher.init(Cipher.ENCRYPT_MODE, pubKey, ecPublicKeySpec.getParams());
  83. return cipher.doFinal(data);
  84. }
  85. /**
  86. * 取得私钥
  87. *
  88. * @param keyMap
  89. * @return
  90. * @throws Exception
  91. */
  92. public static String getPrivateKey(Map<String, Object> keyMap)
  93. throws Exception {
  94. Key key = (Key) keyMap.get(PRIVATE_KEY);
  95. return encryptBASE64(key.getEncoded());
  96. }
  97. /**
  98. * 取得公钥
  99. *
  100. * @param keyMap
  101. * @return
  102. * @throws Exception
  103. */
  104. public static String getPublicKey(Map<String, Object> keyMap)
  105. throws Exception {
  106. Key key = (Key) keyMap.get(PUBLIC_KEY);
  107. return encryptBASE64(key.getEncoded());
  108. }
  109. /**
  110. * 初始化密钥
  111. *
  112. * @return
  113. * @throws Exception
  114. */
  115. public static Map<String, Object> initKey() throws Exception {
  116. BigInteger x1 = new BigInteger(
  117. "2fe13c0537bbc11acaa07d793de4e6d5e5c94eee8", 16);
  118. BigInteger x2 = new BigInteger(
  119. "289070fb05d38ff58321f2e800536d538ccdaa3d9", 16);
  120. ECPoint g = new ECPoint(x1, x2);
  121. // the order of generator
  122. BigInteger n = new BigInteger(
  123. "5846006549323611672814741753598448348329118574063", 10);
  124. // the cofactor
  125. int h = 2;
  126. int m = 163;
  127. int[] ks = { 7, 6, 3 };
  128. ECFieldF2m ecField = new ECFieldF2m(m, ks);
  129. // y^2+xy=x^3+x^2+1
  130. BigInteger a = new BigInteger("1", 2);
  131. BigInteger b = new BigInteger("1", 2);
  132. EllipticCurve ellipticCurve = new EllipticCurve(ecField, a, b);
  133. ECParameterSpec ecParameterSpec = new ECParameterSpec(ellipticCurve, g,
  134. n, h);
  135. // 公钥
  136. ECPublicKey publicKey = new ECPublicKeyImpl(g, ecParameterSpec);
  137. BigInteger s = new BigInteger(
  138. "1234006549323611672814741753598448348329118574063", 10);
  139. // 私钥
  140. ECPrivateKey privateKey = new ECPrivateKeyImpl(s, ecParameterSpec);
  141. Map<String, Object> keyMap = new HashMap<String, Object>(2);
  142. keyMap.put(PUBLIC_KEY, publicKey);
  143. keyMap.put(PRIVATE_KEY, privateKey);
  144. return keyMap;
  145. }
  146. }

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



照旧提供一个测试类:

  1. import static org.junit.Assert.*;
  2. import java.math.BigInteger;
  3. import java.security.spec.ECFieldF2m;
  4. import java.security.spec.ECParameterSpec;
  5. import java.security.spec.ECPoint;
  6. import java.security.spec.ECPrivateKeySpec;
  7. import java.security.spec.ECPublicKeySpec;
  8. import java.security.spec.EllipticCurve;
  9. import java.util.Map;
  10. import org.junit.Test;
  11. /**
  12. *
  13. * @author 梁栋
  14. * @version 1.0
  15. * @since 1.0
  16. */
  17. public class ECCCoderTest {
  18. @Test
  19. public void test() throws Exception {
  20. String inputStr = "abc";
  21. byte[] data = inputStr.getBytes();
  22. Map<String, Object> keyMap = ECCCoder.initKey();
  23. String publicKey = ECCCoder.getPublicKey(keyMap);
  24. String privateKey = 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. String outputStr = new String(decodedData);
  30. System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);
  31. assertEquals(inputStr, outputStr);
  32. }
  33. }

控制台输出:

    1. 公钥:
    2. MEAwEAYHKoZIzj0CAQYFK4EEAAEDLAAEAv4TwFN7vBGsqgfXk95ObV5clO7oAokHD7BdOP9YMh8u
    3. gAU21TjM2qPZ
    4. 私钥:
    5. MDICAQAwEAYHKoZIzj0CAQYFK4EEAAEEGzAZAgEBBBTYJsR3BN7TFw7JHcAHFkwNmfil7w==
    6. 加密前: abc
    7. 解密后: abc