常用加密解密(4)——数字签名

原文链接:https://www.dubby.cn/detail.html?id=9125

之前介绍了《常用加密解密(1)》里面提到了消息摘要,那么这一篇的数字签名和消息摘要有什么区别呢?事实上数字签名就是带上非对称加密的消息摘要。

消息摘要的目的是防数据被篡改;而数字签名是抗否认。

签名的过程是:

总结就是,使用私钥加签,使用公钥验签

import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class RSASignature {

    private static final String KEY_ALGORITHM = "RSA";

    private static final String SIGN_ALGORITHM = "MD5withRSA";

    public static byte[] sign(byte[] keyBytes, byte[] dataBytes) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

        Signature signature = Signature.getInstance(SIGN_ALGORITHM);
        signature.initSign(privateKey);
        signature.update(dataBytes);
        return signature.sign();
    }

    public static boolean verify(byte[] keyBytes, byte[] dataBytes, byte[] sign) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);

        Signature signature = Signature.getInstance(SIGN_ALGORITHM);
        signature.initVerify(publicKey);
        signature.update(dataBytes);
        return signature.verify(sign);
    }
}

测试代码:

import cn.dubby.digital.signature.RSASignature;
import org.apache.commons.codec.binary.Hex;
import org.junit.Assert;
import org.junit.Test;

import java.nio.charset.Charset;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;

public class RSASignatureTest {

    private static final String key_algorithm = "RSA";

    private static final int key_size = 1024;

    private static final String data = "Hello, Dubby";

    @Test
    public void test() throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(key_algorithm);
        keyPairGenerator.initialize(key_size);

        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

        byte[] dataBytes = data.getBytes(Charset.forName("UTF-8"));

        //使用私钥加签
        byte[] sign = RSASignature.sign(privateKey.getEncoded(), dataBytes);

        System.out.println(Hex.encodeHexString(sign));

        //使用公钥验签
        boolean verifyResult = RSASignature.verify(publicKey.getEncoded(), dataBytes, sign);

        Assert.assertTrue(verifyResult);
    }
}

结果:

5363226f4c9a40a0a95fd526b4efa8697036b03b485a663473702e2cdf72e55082584450568b53502ddb11a78ba9ddf3160bda28d13273b15c5597f7e887d5a084bda94f9ffe41699f2d5c821863fa1ec28af6e38c8578a72f66034aa4a1f95e8bcce7b70710ce53af6a3a5c5324e73cc42eff8e6945a256cea89a1b156e346f
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值