zoukankan      html  css  js  c++  java
  • ECC证书操作汇总(ECC certificate operations summary)

    背景介绍

           项目里用到了ECC的证书使用,有一些证书的常规操作,在此进行汇总说明,以便后浪来踏。ECC的public key长度为65字节,第一个字节是标识符0x04,32字节biginteger X, 32字节biginteger Y; private key的长度是 32字节的biginteger。以下代码示例均为ECC secp256r1 曲线。

    协商秘钥

           张三李四要加密通信,只要持有对方的ECC公钥就可以了。在具体交互时采用AES加密的方式,但每次交互AES秘钥是不同的,AES秘钥在交互时也不参与传输。对方通过当次会话传输过来的临时公钥(ECC Eph_pubKey)进行动态计算来获得本次的AES秘钥,然后用以解密数据包。

    import javax.crypto.KeyAgreement;
    
    public static byte[] keyAgree(PrivateKey selfSK, PublicKey otherPK) {
            try {
                KeyAgreement ka = KeyAgreement.getInstance("ECDH");
                ka.init(selfSK);
                ka.doPhase(otherPK, true);
                return ka.generateSecret();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

              举例过程 张三 -> 李四,张三持有李四的长期公钥。

    •           张三:发送 加密 AES = KeyAgree(张三的临时私钥,李四的长期公钥), 传输内容:张三的临时公钥 (65字节固定)+ 密文;
    •           李四:收到 解密 AES = KeyAgree(李四的长期私钥,张三的临时公钥),解密密文得到明文;

               反之,李四 -> 张三 是对等的。

    解析ECC证书&私钥

            将文本证书及私钥文件反序列化为X509 Cert & ECC private key。

            

     1     public static X509Certificate deserialize(String path) {
     2         try {
     3             String cert = Files.lines(Paths.get(path))
     4                                .filter(line -> !line.startsWith("-----"))
     5                                .collect(Collectors.joining());
     6             if (StringUtils.isBlank(cert)) {
     7                 return null;
     8             }                   
     9             CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
    10             ByteArrayInputStream bais = new ByteArrayInputStream(Base64.decodeBase64(base64Cert));
    11             return (X509Certificate) (certFactory.generateCertificate(bais));
    12         } catch (IOException e) {
    13             e.printStackTrace();
    14         }
    15         return null;
    16     }
    17 
    18 
    19 
    20     public static PrivateKey deserialize(String path) {
    21         try {
    22             String key = Files.lines(Paths.get(path))
    23                               .filter(line -> !line.startsWith("-----"))
    24                               .collect(Collectors.joining());
    25             if (StringUtils.isBlank(key)) {
    26                 return null;
    27             }
    28 
    29             EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(key));
    30             KeyFactory kf = KeyFactory.getInstance("EC");
    31             return kf.generatePrivate(privateKeySpec);
    32         } catch (Exception e) {
    33             e.printStackTrace();
    34         }
    35         return null;
    36     }

    十六进制字符串公私钥反序列化

              How to convert hex string to ECC public key ?

     1     public static PublicKey deserializePubKey(String hexPubKey) throws Exception {
     2         byte[] pubKey = Hex.decode(hexPubKey)
     3         byte[] x = Arrays.copyOfRange(pubKey, 1, 33); // the first byte is 0x04 flag, ignored
     4         byte[] y = Arrays.copyOfRange(pubKey, 33, pubKey.length);
     5         ECPoint w = new ECPoint(new BigInteger(1, x), new BigInteger(1, y));
     6         KeyFactory kf = KeyFactory.getInstance("EC");
     7         return kf.generatePublic(new ECPublicKeySpec(w, ecParameterSpecForP256()));
     8     }
     9 
    10     public static PrivateKey deserializePriKey(String hexPriKey) throws Exception {
    11         KeyFactory kf = KeyFactory.getInstance("EC");
    12         return kf.generatePrivate(new ECPrivateKeySpec(new BigInteger(Hex.decode(hexPriKey)), ecParameterSpecForP256()));
    13     }
    14 
    15     private static ECParameterSpec ecParameterSpecForP256() throws Exception {
    16         AlgorithmParameters params = AlgorithmParameters.getInstance("EC");
    17         params.init(new ECGenParameterSpec("secp256r1"));
    18         return params.getParameterSpec(ECParameterSpec.class);
    19     }

    以上。

  • 相关阅读:
    《数据通信与网络》笔记--数据链路层的成帧
    设计模式10---设计模式之原型模式(Prototype)
    Yii 控制dropdownlist / select 控件的宽度和 option 的宽度
    [置顶] 如何vs在cocos2dx项目中打印中文
    mongodb实现简单的增删改查
    北京和硅谷在创新方面的区别
    Android 解决Gallery下ScrollView滑动事件冲突
    Java 授权内幕--转载
    JAVA 上加密算法的实现用例---转载
    基于事件的 NIO 多线程服务器--转载
  • 原文地址:https://www.cnblogs.com/sinsonglew/p/15704200.html
Copyright © 2011-2022 走看看