【安全性】java数字签名

java数字签名

1.密钥对生成类:RSASignGenerate.java

package pers.li;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;

/**
 * create by lishengbo on 2018-04-24 17:48
 * <p>
 * 数字签名生成工具类
 */
public class RSASignGenerate {


    /**
     * RSA -- 数字签名生成公私钥
     * 公钥公布出去,私钥自己留着
     * @Param name-- 针对哪个公司生成的名称
     * @return
     */
    public static Map<String, String> GenerateKeyPair(String name) {
        Map<String, String> map = new HashMap<>();
        try {
            java.security.KeyPairGenerator keygen = java.security.KeyPairGenerator
                    .getInstance("RSA");
            SecureRandom secrand = new SecureRandom();
            // 初始化随机产生器
            secrand.setSeed(name.getBytes());
            keygen.initialize(512, secrand);
            KeyPair keys = keygen.genKeyPair();

            PublicKey pubkey = keys.getPublic();
            PrivateKey prikey = keys.getPrivate();

            String pubKey = bytesToHexStr(pubkey.getEncoded());

            String priKey = bytesToHexStr(prikey.getEncoded());

            System.out.println("pubKey=" + pubKey);
            System.out.println("priKey=" + priKey);
            map.put("priKey", priKey);
            map.put("pubKey", pubKey);
            System.out.println("生成密钥对成功");
        } catch (java.lang.Exception e) {
            e.printStackTrace();
            System.out.println("生成密钥对失败");
        };
        return map;
    }


    /**
     * Transform the specified byte into a Hex String form.
     */
    public static final String bytesToHexStr(byte[] bcd) {
        StringBuffer s = new StringBuffer(bcd.length * 2);

        for (int i = 0; i < bcd.length; i++) {
            s.append(bcdLookup[(bcd[i] >>> 4) & 0x0f]);
            s.append(bcdLookup[bcd[i] & 0x0f]);
        }

        return s.toString();
    }

    /**
     * Transform the specified Hex String into a byte array.
     */
    public static final byte[] hexStrToBytes(String s) {
        byte[] bytes;

        bytes = new byte[s.length() / 2];

        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) Integer.parseInt(s.substring(2 * i, 2 * i + 2),
                    16);
        }
        return bytes;

    }
    private static final char[] bcdLookup = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
}

2.私钥签名:SignatureData.js

package pers.li;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;

/**
 * 编写发送者的功能:首先通过私钥加密待输出数据Data,并输出Data和签名后的Data;
 */
 public static String  sign(String priKey,String info) {
        try {
            PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(hexStrToBytes(priKey));
            KeyFactory keyf = KeyFactory.getInstance("RSA");
            PrivateKey myprikey = keyf.generatePrivate(priPKCS8);
            // 用私钥对信息生成数字签名
            java.security.Signature signet = java.security.Signature.getInstance("MD5withRSA");
            signet.initSign(myprikey);
            // 要签名的信息
            signet.update(info.getBytes("ISO-8859-1"));
            // 对信息的数字签名
            byte[] signed = signet.sign();
            System.out.println("signed(签名内容)原值=" + bytesToHexStr(signed));
            System.out.println("info(原值)=" + info);
            System.out.println("签名并生成文件成功");
            return bytesToHexStr(signed);
        } catch (java.lang.Exception e) {
            e.printStackTrace();
            System.out.println("签名并生成文件失败");
        };
        return null;
    }

    /**
     * Transform the specified byte into a Hex String form.
     */
    public static final String bytesToHexStr(byte[] bcd) {
        StringBuffer s = new StringBuffer(bcd.length * 2);

        for (int i = 0; i < bcd.length; i++) {
            s.append(bcdLookup[(bcd[i] >>> 4) & 0x0f]);
            s.append(bcdLookup[bcd[i] & 0x0f]);
        }

        return s.toString();
    }

    /**
     * Transform the specified Hex String into a byte array.
     */
    public static final byte[] hexStrToBytes(String s) {
        byte[] bytes;

        bytes = new byte[s.length() / 2];

        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) Integer.parseInt(s.substring(2 * i, 2 * i + 2),
                    16);
        }

        return bytes;
    }

    private static final char[] bcdLookup = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
}

3.公钥解密:VerifySignature.java

package pers.li;
import java.security.DomainCombiner;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;

import static pers.li.GenerateKeyPair.hexStrToBytes;

/**
 * 编写接收者的功能:使用发送者的公钥来验证发送过来的加密Data,判断签名的合法性
 * 签名并生成文件成功
 */
public class VerifySignature {

    public static boolean verifySign(String pubkeyvalue, String info, String sign) {
        try {
            //这是GenerateKeyPair输出的公钥编码
            X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(hexStrToBytes(pubkeyvalue));
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey pubKey = keyFactory.generatePublic(bobPubKeySpec);
            //这是SignatureData输出的数字签名
            byte[] signed = hexStrToBytes(sign);
            java.security.Signature signetcheck = java.security.Signature.getInstance("MD5withRSA");
            signetcheck.initVerify(pubKey);
            signetcheck.update(info.getBytes());
            if (signetcheck.verify(signed)) {
                System.out.println("签名正常");
            } else {
                System.out.println("非签名正常");
            }
            return signetcheck.verify(signed);
        } catch (java.lang.Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}

4.测试:test.java

package pers.li;
import java.util.Map;
public class test {

    public static void main(String[] args) {
        Map<String, String> map = RSASignGenerate.GenerateKeyPair("www.baidu.com");
        String priKey = map.get("priKey");
        String pubKey = map.get("pubKey");
        String info = "orderId=10dkfadsfksdkssdkd&amount=80&orderTime=20060509";
        String signed = SignatureData.sign(priKey, info);
        boolean b = VerifySignature.verifySign(pubKey, info, signed);
    }
}

5.测试结果:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皇夜_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值