RSA签名介绍及例子

最近接到一个需求,对接滴滴进行数据传输,其中用到了签名,研究了一下,现在记录下来。

说到这里,首先得知道什么是RSA。RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。
对极大整数做因数分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。假如有人找到一种快速因数分解的算法的话,那么用RSA加密的信息的可靠性就肯定会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA钥匙才可能被强力方式解破。世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。

通常先生成一对RSA 密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位。这就使加密的计算量很大。为减少计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。对方收到信息后,用不同的密钥解密并可核对信息摘要。

以上内容来在百度百科。

更重要的数据则选择2048来保证数据的安全。

下面是加密签名、解密的例子

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

/**
 * @ClassName TestSignature
 * @Author king
 * @Date 2020/3/27 10:09
 * @Version V1.0
 **/
public class TestSignature {
    public static void main(String[] args) throws Exception {
        KeyPair keyPair = generateKeyPair();
        String privateKey = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());
        String publicKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());

        String data = "data will be signature";
        String signatureData = signature(data, privateKey);
        boolean verify = verify(signatureData, data, publicKey);
        System.out.println(verify);

    }

    /**
     * @return java.security.KeyPair
     * @Description 生成秘钥对
     * @Date 2020/3/27 10:12
     **/
    public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator rsa = KeyPairGenerator.getInstance("RSA");
        rsa.initialize(2048);
        return rsa.generateKeyPair();
    }

    /**
     * @return String
     * @Author wangwei
     * @Description 加签
     * @Date 2020/3/27 10:18
     **/
    public static String signature(String data, String privateKey) throws Exception {
        Signature signature = Signature.getInstance("MD5withRSA");
        signature.initSign(generatePrivateKey(privateKey));
        signature.update(data.getBytes());
        byte[] sign = signature.sign();
        return Base64.getEncoder().encodeToString(sign);
    }

    /**
     * @return java.security.PrivateKey
     * @Description 根据String生成privateKey
     * @Date 2020/3/27 10:30
     * @Param [string]
     **/
    public static PrivateKey generatePrivateKey(String string) throws NoSuchAlgorithmException, InvalidKeySpecException {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        byte[] decode = Base64.getDecoder().decode(string.getBytes());
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(decode);
        return keyFactory.generatePrivate(pkcs8EncodedKeySpec);
    }

    /**
     * @return java.security.PublicKey
     * @Description 根据String生成PublicKey
     * @Date 2020/3/27 10:42
     * @Param [string]
     **/
    public static PublicKey generatePublicKey(String string) throws NoSuchAlgorithmException, InvalidKeySpecException {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        byte[] decode = Base64.getDecoder().decode(string.getBytes());
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(decode);
        return keyFactory.generatePublic(x509EncodedKeySpec);
    }

    /**
     * @return boolean
     * @Description 校验数据是否正确
     * @Date 2020/3/27 10:42
     * @Param [signatureData, data, publicKey]
     **/
    public static boolean verify(String signatureData, String data, String publicKey) throws InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        PublicKey publicKey1 = generatePublicKey(publicKey);
        Signature signature = Signature.getInstance("MD5withRSA");
        signature.initVerify(publicKey1);
        signature.update(data.getBytes());
        return signature.verify(Base64.getDecoder().decode(signatureData));

    }
}

你可能感兴趣的:(java,rsa,java)