当前位置:   article > 正文

ECC算法

ecc算法

一、ECC算法介绍

      ECC全称为“Ellipse Curve Ctyptography”,是一种基于椭圆曲线数学的公开密钥加密算法。说到非对称加密算法,大家一般印象是RSA算法,ECC算法的主要优势是可以使用较小的密钥病提供相当高等级的安全,ECC164位密钥提供的安全级可以与RSA 1024位密钥相当。ECC算法相比RSA、DSA算法有以下优势:

  • 同等安全级别要求下,ECC算法计算量小,处理速度快,虽然同等秘钥长度下,ECC的计算更为复杂,但是ECC算法只要较小长度的秘钥就可以达到RSA、DSA算法长秘钥才能达到的安全等级,所以总体上ECC算法性能上更优;

  • 存储空间小,因为同等级安全要求,ECC的秘钥长度要小很多,所以占用的存储空间小;

  • 带宽要求低,虽然长消息场景ECC算法并没有优势,但是短消息场景,ECC要求的带宽是较低的;

  • ECC算法不仅可以用于加解密(但ECIES当前还未被NIST认可)、签名验签,还可以与DH结合使用,用于密钥磋商,这个密钥交换算法称为ECDH,交换双方可以在不共享任何秘密的情况下协商出一个共享密钥(交互算法可以直接根据自己的私钥和对方的公钥支持生产共享秘钥);

二、ECC算法实现

  1. import org.bouncycastle.jce.provider.BouncyCastleProvider;
  2. import org.bouncycastle.util.encoders.Base64;
  3. import javax.crypto.Cipher;
  4. import javax.crypto.KeyAgreement;
  5. import java.security.*;
  6. import java.security.spec.ECGenParameterSpec;
  7. import java.security.spec.PKCS8EncodedKeySpec;
  8. import java.security.spec.X509EncodedKeySpec;
  9. /**
  10. * ECC算法工具类
  11. */
  12. public class ECCUtil {
  13. /**
  14. * 算法名称
  15. */
  16. private static final String ALGORITHM = "ECDSA";
  17. /**
  18. * BouncyCastle provider
  19. */
  20. private static final String PROVIDER = "BC";
  21. private static final String ENCRYPT_ALGORITHM = "ECIES";
  22. /**
  23. * 密钥交换算法
  24. */
  25. private static final String SHARE_KEY_ALGORITHM = "ECDH";
  26. /**
  27. * 签名算法
  28. */
  29. private static final String SIGN_PROVIDER = "SHA256withECDSA";
  30. static {
  31. Security.addProvider(new BouncyCastleProvider());
  32. }
  33. /**
  34. * 生产公私钥对
  35. *
  36. * @return ECC公私钥
  37. * @throws Exception
  38. */
  39. public static KeyPair generateKeyPair() throws Exception {
  40. KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM, PROVIDER);
  41. // 指定EC曲线类型生成密钥对
  42. ECGenParameterSpec spec = new ECGenParameterSpec("curve25519");
  43. keyPairGenerator.initialize(spec, SecureRandom.getInstance("SHA1PRNG"));
  44. return keyPairGenerator.generateKeyPair();
  45. }
  46. /**
  47. * 读取公钥(base64编码)
  48. * @param keyPair
  49. * @return
  50. */
  51. public static String getPublicKey(KeyPair keyPair) {
  52. return Base64.toBase64String(keyPair.getPublic().getEncoded());
  53. }
  54. /**
  55. * 读取私钥(base64编码)
  56. * @param keyPair
  57. * @return
  58. */
  59. public static String getPrivateKey(KeyPair keyPair) {
  60. return Base64.toBase64String(keyPair.getPrivate().getEncoded());
  61. }
  62. /**
  63. * 构建公钥对象(输入为base64编码字符串)
  64. * @param keyStr
  65. * @return
  66. * @throws Exception
  67. */
  68. public static PublicKey str2PublicKey(String keyStr) throws Exception {
  69. byte[] publicKey = Base64.decode(keyStr);
  70. X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);
  71. KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM, PROVIDER);
  72. return keyFactory.generatePublic(keySpec);
  73. }
  74. /**
  75. * 构建私钥对象(输入为base64编码字符串)
  76. * @param keyStr
  77. * @return
  78. * @throws Exception
  79. */
  80. public static PrivateKey str2PrivateKey(String keyStr) throws Exception {
  81. byte[] privateKey = Base64.decode(keyStr);
  82. PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey);
  83. KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM, PROVIDER);
  84. return keyFactory.generatePrivate(keySpec);
  85. }
  86. /**
  87. * 加密数据
  88. * @param publicKey 公钥
  89. * @param data 数据
  90. * @return
  91. * @throws Exception
  92. */
  93. public static byte[] encrypt(PublicKey publicKey, byte[] data) throws Exception {
  94. Cipher cipher = Cipher.getInstance(ENCRYPT_ALGORITHM, PROVIDER);
  95. cipher.init(Cipher.ENCRYPT_MODE, publicKey);
  96. return cipher.doFinal(data);
  97. }
  98. /**
  99. * 解密数据
  100. * @param privateKey 私钥
  101. * @param data 数据
  102. * @return
  103. * @throws Exception
  104. */
  105. public static byte[] decrypt(PrivateKey privateKey, byte[] data) throws Exception {
  106. Cipher cipher = Cipher.getInstance(ENCRYPT_ALGORITHM, PROVIDER);
  107. cipher.init(Cipher.DECRYPT_MODE, privateKey);
  108. return cipher.doFinal(data);
  109. }
  110. /**
  111. * 数据签名
  112. * @param privateKey 私钥
  113. * @param data 数据
  114. * @return
  115. * @throws Exception
  116. */
  117. public static byte[] sign(PrivateKey privateKey, byte[] data) throws Exception {
  118. Signature signature = Signature.getInstance(SIGN_PROVIDER);
  119. signature.initSign(privateKey);
  120. signature.update(data);
  121. return signature.sign();
  122. }
  123. /**
  124. * 数据验签
  125. * @param publicKey 公钥
  126. * @param data 数据
  127. * @param sign 数据签名
  128. * @return
  129. * @throws Exception
  130. */
  131. public static boolean verify(PublicKey publicKey, byte[] data, byte[] sign) throws Exception {
  132. Signature signature = Signature.getInstance(SIGN_PROVIDER);
  133. signature.initVerify(publicKey);
  134. signature.update(data);
  135. return signature.verify(sign);
  136. }
  137. /**
  138. * 生成共享密钥:用于密钥交换,客户端和服务器端双方各自生成一对公私钥,然后客户端使用自己的私钥和服务器的公钥生成一个共享秘钥,
  139. * 服务端使用自己的私钥和客户端的公钥生成一个共享秘钥,这两个秘钥结果相同,可用于对称加密
  140. * @param privateKey
  141. * @param publicKey
  142. * @return
  143. * @throws Exception
  144. */
  145. public static byte[] genShareKey(PublicKey publicKey, PrivateKey privateKey) throws Exception {
  146. KeyAgreement keyAgreement = KeyAgreement.getInstance(SHARE_KEY_ALGORITHM, PROVIDER);
  147. keyAgreement.init(privateKey);
  148. keyAgreement.doPhase(publicKey, true);
  149. return keyAgreement.generateSecret();
  150. }
  151. }

三、ECC算法应用场景

 当前在比特币中ECC算法用的比较多,但是随着计算能力的增强,安全等级要求越来越高,RSA算法的秘钥长度已经太长,弊端比较大,可以预见ECC算法应用会越来越广,比如:

  • 性能要求不高的单向数据加密传输场景(非对称加密相比对称加密算法AES性能差别巨大),例如用于长期自动登录身份的校验等;

  • 双方预制校验身份,比如物理网场景平台一份公私钥,设备一份公私钥,平台发放设备时把设备id和设备公钥预制到进去,这样设备上线后就可以与平台认证通信等;

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/612161
推荐阅读
相关标签
  

闽ICP备14008679号