ECCDSA加签验签工具类, base64编码

对传入参数, 按照key首字母降序排序
json序列化后, 进行 sha256 加密, 结果使用base64编码获取hash
hash进行ECCDSA加密

package cn.box365.ipfs.utils;

import com.alibaba.fastjson.JSONObject;
import sun.misc.BASE64Decoder;

import javax.xml.bind.DatatypeConverter;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;

/**
 * ECCDSA加签验签工具类
 * @author Administrator
 *
 */
public class ECDSAUtil {
	
	 private static final String SIGNALGORITHMS = "SHA256withECDSA";
	 private static final String ALGORITHM = "EC";
	 private static final String SECP256K1 = "secp256k1";

    public static final String PRIVATE_KEY_PATH = "\\src\\main\\resources\\pem\\eccprivate_pkcs8.pem";
    public static final String PUBLIC_KEY_PATH = "\\src\\main\\resources\\pem\\eccpublic_pkcs8.pem";

    public static String HOST_URL;


    static {
        if (BlackBoxHttpUtil.IF_FORMAL) {
            //ipfs正式
            HOST_URL = "https://183.223.56.103:8080/send";
        } else {
            //测试地址
            HOST_URL = "https://183.223.56.103:8080/send";
        }
    }

    public static void main(String[] args) throws Exception {
        //1. 生成公钥私钥
        //生成公钥私钥
        KeyPair keyPair1 = getKeyPair();
        PublicKey publicKey1 = keyPair1.getPublic();
        PrivateKey privateKey1 = keyPair1.getPrivate();
        //密钥转16进制字符串
        String publicKey = Base64.getEncoder().encodeToString(publicKey1.getEncoded());
        String privateKey = Base64.getEncoder().encodeToString(privateKey1.getEncoded());
        System.out.println("生成公钥:"+publicKey);
        System.out.println("生成私钥:"+privateKey);
        //16进制字符串转密钥对象
        PrivateKey privateKey2 = getPrivateKey(privateKey);
        PublicKey publicKey2 = getPublicKey(publicKey);
        //加签验签
        String data="需要签名的数据";
        String signECDSA = signECDSA(privateKey2, data);
        System.out.println("signECDSA签名结果:" + signECDSA);
        signECDSA = signECDSA(privateKey2, data);
        boolean verifyECDSA = verifyECDSA(publicKey2, signECDSA, data);
        System.out.println("验签结果:"+verifyECDSA);

        System.out.println();
        System.out.println();

        /**
         * 注意8是整形
         序列化:  {"address":"t1mq2zk4dtcxm42sx76djtezlgkyp3gbb4gdcidba","amount":"0.3","nonce":8}
         hash:  0lVEvbGmgdiWkkk4N4cGXMQiD2C6i00f8Hr0ggwZvpc=
         */
        Map<String,Object> map = new HashMap<>();
        map.put("address","t1mq2zk4dtcxm42sx76djtezlgkyp3gbb4gdcidba");
        map.put("amount","0.3");
        map.put("nonce",12);

        String jsonString = getDataSortJsonString(map);
        System.out.println("1.jsonString:" + jsonString);

        String signECDSA1 = signECDSAByPem(jsonString);
        System.out.println("2.签名结果:" + signECDSA1);

        boolean verifyECDSA1 = verifyECDSAByPem(signECDSA1, jsonString);
        System.out.println("验签结果:"+verifyECDSA1);

        String result = sendPost(HOST_URL, BlackBoxHttpUtil.buildParamObj(map), signECDSA1);
        System.out.println("请求result:"+result);
    }


    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url
     *            发送请求的 URL
     * @param param
     *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param, String auth)  throws Exception{
        PrintWriter out = null;
        OutputStream os = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("auth", auth);
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Content-Type", "application/json");

            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            os = conn.getOutputStream();
            os.write(param.getBytes("utf-8"));

            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(),"utf-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
                if (os != null) {
                    os.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 加签 通过PEM
     * @param data 数据
     * @return
     */
    public static String signECDSAByPem(String data) {
        String result = "";
        try {
            PrivateKey privateKey = getPrivateKeyByPem();
            //执行签名
            Signature signature = Signature.getInstance(SIGNALGORITHMS);
            signature.initSign(privateKey);
            signature.update(data.getBytes());
            byte[] sign = signature.sign();
            return Base64.getEncoder().encodeToString(sign);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 通过pemprivate key
     * @return
     * @throws Exception
     */
    public static PrivateKey getPrivateKeyByPem() throws Exception {

        File directory = new File("");//参数为空
        String courseFile = directory.getCanonicalPath() ;
        String privateKeyPath = courseFile + PRIVATE_KEY_PATH;

        BASE64Decoder base64decoder = new BASE64Decoder();
        BufferedReader br8 = new BufferedReader(new FileReader(privateKeyPath));
        String s = br8.readLine();
        String str = "";
        s = br8.readLine();
        while (s.charAt(0)!= '-'){
            str += s + "\r";
            s = br8.readLine();
        }
        byte[] buffer8 =base64decoder.decodeBuffer(str) ;
        br8.close();

        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer8);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePrivate(keySpec);
    }

    /**
     * java 对字符串排序, 并返回json数据
     * @return
     * @throws Exception
     */
    public static String getDataSortJsonString(Map<String,Object> data) throws Exception {

        Set<String> keySet = data.keySet();
        String[] keyArray = keySet.toArray(new String[keySet.size()]);
        Arrays.sort(keyArray);

        JSONObject jsonObject = new JSONObject(true);
        for (String k : keyArray) {
            if (k.equals(BlackBoxHttpUtil.FIELD_SIGN) || k.equals(BlackBoxHttpUtil.FIELD_SUCCESS) ) {
                continue;
            }
            jsonObject.put(k,data.get(k));
        }

        return jsonObject.toJSONString();
    }


    /**
     * 加签
     * @param privateKey 私钥
     * @param data 数据
     * @return
     */
    public static String signECDSA(PrivateKey privateKey, String data) {
        String result = "";
        try {
            //执行签名
            Signature signature = Signature.getInstance(SIGNALGORITHMS);
            signature.initSign(privateKey);
            signature.update(data.getBytes());
            byte[] sign = signature.sign();
            return Base64.getEncoder().encodeToString(sign);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 验签
     * @param publicKey 公钥
     * @param signed 签名
     * @param data 数据
     * @return
     */
    public static boolean verifyECDSA(PublicKey publicKey, String signed, String data) {
        try {
            //验证签名
            Signature signature = Signature.getInstance(SIGNALGORITHMS);
            signature.initVerify(publicKey);
            signature.update(data.getBytes());
            byte[] hex = Base64.getDecoder().decode(signed);
            boolean bool = signature.verify(hex);
            // System.out.println("验证:" + bool);
            return bool;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 验签
     * @param signed 签名
     * @param data 数据
     * @return
     */
    public static boolean verifyECDSAByPem(String signed, String data) {
        try {
            PublicKey publicKey = getPublicKeyByPem();

            //验证签名
            Signature signature = Signature.getInstance(SIGNALGORITHMS);
            signature.initVerify(publicKey);
            signature.update(data.getBytes());
            byte[] hex = Base64.getDecoder().decode(signed);
            boolean bool = signature.verify(hex);
            // System.out.println("验证:" + bool);
            return bool;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


    /**
     * 从string转private key
     * @param key 私钥的字符串
     * @return
     * @throws Exception
     */
    public static PrivateKey getPrivateKey(String key) throws Exception {

        byte[] bytes = DatatypeConverter.parseBase64Binary(key);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePrivate(keySpec);
    }

    /**
     * 从string转publicKey
     * @param key 公钥的字符串
     * @return
     * @throws Exception
     */
    public static PublicKey getPublicKey(String key) throws Exception {

        byte[] bytes = DatatypeConverter.parseBase64Binary(key);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePublic(keySpec);
    }


    /**
     * 从string转publicKey
     * @return
     * @throws Exception
     */
    public static PublicKey getPublicKeyByPem() throws Exception {
        File directory = new File("");//参数为空
        String courseFile = directory.getCanonicalPath() ;
        String privateKeyPath = courseFile + PUBLIC_KEY_PATH;

        BASE64Decoder base64decoder = new BASE64Decoder();
        BufferedReader br8 = new BufferedReader(new FileReader(privateKeyPath));
        String s = br8.readLine();
        String str = "";
        s = br8.readLine();
        while (s.charAt(0)!= '-'){
            str += s + "\r";
            s = br8.readLine();
        }
        byte[] buffer8 =base64decoder.decodeBuffer(str) ;
        br8.close();

        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer8);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePublic(keySpec);
    }


    /**
     * 生成密钥对
     * @return
     * @throws Exception
     */
    public static KeyPair getKeyPair() throws Exception {
        ECGenParameterSpec ecSpec = new ECGenParameterSpec(SECP256K1);
        KeyPairGenerator kf = KeyPairGenerator.getInstance(ALGORITHM);
        kf.initialize(ecSpec, new SecureRandom());
        KeyPair keyPair = kf.generateKeyPair();
        return keyPair;
    }

}
 

私钥
eccprivate_pkcs8.pem

-----BEGIN ecc private key-----
MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIAaCofgjFSk5g6UMzu
SRLkIKGYeHFAnVKgKIDS0UJUiNbqf7K/boAFsHAPurVp4h+nYxytlfGENeejrq3H
XO7kR4KhgYkDgYYABAFnxEML0ZCwXIXqAOUX3y1dta5b4gLoyQOAUC0W098Fy4Om
B9VF+Bv3TE/ovwKnmoulBlpbVPD8JBkWLuvQQAdKWwD8cuoGM/6EbOyS926ZJ33A
AZviVoY7y+dOf5QgjNKJfLQe9Uqam2h1J9DEVzEttAjr/91eJozihJvsvhVRVqML
Rw==
-----END ecc private key-----

公钥
eccpublic_pkcs8.pem

-----BEGIN ecc public key-----
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBZ8RDC9GQsFyF6gDlF98tXbWuW+IC
6MkDgFAtFtPfBcuDpgfVRfgb90xP6L8Cp5qLpQZaW1Tw/CQZFi7r0EAHSlsA/HLq
BjP+hGzskvdumSd9wAGb4laGO8vnTn+UIIzSiXy0HvVKmptodSfQxFcxLbQI6//d
XiaM4oSb7L4VUVajC0c=
-----END ecc public key-----
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Java中,可以使用Base64编码对数据进行密和解密。以下是一个示例的Java Base64解密工具类: ```java import java.util.Base64; public class Base64Utils { public static String encode(String data) { byte[] bytes = data.getBytes(); byte[] encodedBytes = Base64.getEncoder().encode(bytes); return new String(encodedBytes); } public static String decode(String data) { byte[] bytes = data.getBytes(); byte[] decodedBytes = Base64.getDecoder().decode(bytes); return new String(decodedBytes); } public static void main(String[] args) { String originalData = "Hello, World!"; String encodedData = encode(originalData); String decodedData = decode(encodedData); System.out.println("原始数据: " + originalData); System.out.println("密后的数据: " + encodedData); System.out.println("解密后的数据: " + decodedData); } } ``` 在上面的示例中,`encode`方法用于将字符串进行Base64编码,而`decode`方法用于将Base64编码的字符串进行解码。两个方法的返回值均为字符串类型。 在`main`方法中,我们可以利用这两个方法来测试解密的功能。首先,将原始数据字符串传入`encode`方法进行编码,得到密后的数据字符串;然后,将密后的数据字符串传入`decode`方法进行解码,得到解密后的数据字符串。 最后,通过使用`System.out.println()`方法将原始数据、密后的数据和解密后的数据打印出来,以便观察解密的效果。 需要注意的是,这里使用的是Java 8中的`java.util.Base64`类,该类提供了编码和解码的方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值