Linux(openSSL)上RSA密钥生成和使用(java)

openssl 公私钥生成

生成私钥

openssl genrsa -out rsa_private_key.pem 1024

生成公钥

openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout
## 查看
hzliubenlong@hzbxs-loantest63:~$ ll
total 8
-rw-r--r-- 1 hzliubenlong neteaseusers 891 May 13 16:18 rsa_private_key.pem
-rw-r--r-- 1 hzliubenlong neteaseusers 272 May 13 16:18 rsa_public_key.pem

此时Java代码还加载不了这里生成的私钥,必须进行pkcs8转码,否则会报错.

openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt
将转码后的秘钥保存使用即可。只有这样,Java代码才可以读取到改私钥

hzliubenlong@hzbxs-loantest63:~$ openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt
-----BEGIN PRIVATE KEY-----
MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAO7Dey8pwuOy0xdw
RpOB78WhkwaygXNr5roXEsEapQTBFXJFCRcLzP7vnbrM2M0H4dOTdubIrpVz5cUu
bBJ+t1A3Mzhw14jFDyaILMdovj/DafbR6zvfisovWJe1Pa6kW0DUsLPfjdGBZcr3
sCzRJXFSkKpu5ndR9XERzbYQiCRlAgMBAAECgYEAy0skQqcDKo7jT0youwXimtqU
7hnlQNp5rK7iqArAwMiKMy52q+m/VL2/BgNPAVwZuuUPUzdB9zykQfzhxemguAYU
KmRYCFJWa3yCWCoFm7UfyuW3PwlTwI7vIZ5MdhZBj8i8yxOkSBWeNH2fxIf7WQFh
Y+8YKsuX5eeUmtACKo0CQQD38bx1DbZHR+lCq1Hkd0a7pf5dZwfoFaiiAJN9a1ja
VTaS+HRiA1ARj1sYMRJlQIFPcAvEU9lzPZs5qG4+DyxDAkEA9oVimhTdg5G140wC
Rpr8C7MRuNdBfkOwihVXJzDTrFezlXwFaGBN6G3uvQS9D/Fkrx6hwZbCiUcRDSeP
ERq2NwJBAIQXyoJGCt1Q52m4YgmorgtctPZH5MN1foDIc8s2vICdM1T7fu2UvDyO
tkZeJmHBCuMqW2p+DXRC1wbRv+HaLYcCQQDHy4UFceGx71cl14WEqbma1c+IKlU3
Oy8KSo9vAOCdLhsrDO/pDxw1Q1uZMAz2reK3FzFsD36s+b71FVmbODXzAkEA3RTP
atASq6RJmHe2CexpfkUE5eXKFh2aiZEA//ropX0TJyIQOZuorzryDbyn+xu9dP1L
6DB/WbWhhHYKZg5F8A==
-----END PRIVATE KEY-----

Java代码

import org.apache.commons.lang3.ArrayUtils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class RSAUtils {
    public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
    private static String RSA = "RSA";

    public static KeyPair generateRSAKeyPair() {
        return generateRSAKeyPair(1024);
    }

    public static KeyPair generateRSAKeyPair(int keyLength) {
        try {
            KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA);
            kpg.initialize(keyLength);
            return kpg.genKeyPair();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }


    public static byte[] encryptData(byte[] data, PublicKey publicKey) {
        try {
            byte[] dataReturn = new byte[0];
            Cipher cipher = Cipher.getInstance(RSA);
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);

// 加密时超过117字节就报错。为此采用分段加密的办法来加密
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < data.length; i += 100) {
                byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i,
                        i + 100));
                sb.append(new String(doFinal));
                dataReturn = ArrayUtils.addAll(dataReturn, doFinal);
            }

            return dataReturn;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 验证数字签名函数入口
     *
     * @param plainBytes 待验签明文字节数组
     * @param signBytes  待验签签名后字节数组
     * @param publicKey  验签使用公钥
     * @return 验签是否通过
     * @throws Exception
     */
    public static boolean verifyDigitalSign(byte[] plainBytes, byte[] signBytes, PublicKey publicKey) throws Exception {
        boolean isValid = false;
        try {
            Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
            signature.initVerify(publicKey);
            signature.update(plainBytes);
            isValid = signature.verify(signBytes);
            return isValid;
        } catch (NoSuchAlgorithmException e) {
            throw new Exception(String.format("验证数字签名时没有[%s]此类算法", SIGN_ALGORITHMS));
        } catch (InvalidKeyException e) {
            throw new Exception("验证数字签名时公钥无效");
        } catch (SignatureException e) {
            throw new Exception("验证数字签名时出现异常");
        }
    }

    public static String rsaSign(byte[] encryptByte, PrivateKey privateKey) {
        try {
            Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
            signature.initSign(privateKey);
            signature.update(encryptByte);
            byte[] signed = signature.sign();
            return (new BASE64Encoder()).encodeBuffer(signed);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static byte[] decryptData(byte[] encryptedData, PrivateKey privateKey) {
        try {
            Cipher cipher = Cipher.getInstance(RSA);
            cipher.init(Cipher.DECRYPT_MODE, privateKey);

            // 解密时超过128字节就报错。为此采用分段解密的办法来解密
            byte[] dataReturn = new byte[0];
            for (int i = 0; i < encryptedData.length; i += 128) {
                byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(encryptedData, i,
                        i + 128));
                dataReturn = ArrayUtils.addAll(dataReturn, doFinal);
            }

            return dataReturn;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static boolean doCheck(byte[] encryptByte, byte[] bs, PublicKey publicKey) {
        try {
            Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
            signature.initVerify(publicKey);
            signature.update(encryptByte);
            return signature.verify(bs);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    public static PublicKey getPublicKey(byte[] keyBytes) throws NoSuchAlgorithmException,
            InvalidKeySpecException {
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA);
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
    }

    public static PrivateKey getPrivateKey(byte[] keyBytes) throws NoSuchAlgorithmException,
            InvalidKeySpecException {
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA);
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return privateKey;
    }

    public static PublicKey getPublicKey(String modulus, String publicExponent)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        BigInteger bigIntModulus = new BigInteger(modulus);
        BigInteger bigIntPrivateExponent = new BigInteger(publicExponent);
        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus, bigIntPrivateExponent);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA);
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
    }

    public static PrivateKey getPrivateKey(String modulus, String privateExponent)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        BigInteger bigIntModulus = new BigInteger(modulus);
        BigInteger bigIntPrivateExponent = new BigInteger(privateExponent);
        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus, bigIntPrivateExponent);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA);
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return privateKey;
    }

    public static PublicKey loadPublicKey(String publicKeyStr) throws Exception {
        byte[] buffer = (new BASE64Decoder()).decodeBuffer(publicKeyStr);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
        return keyFactory.generatePublic(keySpec);
    }

    public static PrivateKey loadPrivateKey(String privateKeyStr) throws Exception {
        byte[] buffer = (new BASE64Decoder()).decodeBuffer(privateKeyStr);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA);
        return keyFactory.generatePrivate(keySpec);
    }

    public static PublicKey loadPublicKey(InputStream in) throws Exception {
        return loadPublicKey(readKey(in));
    }

    public static PrivateKey loadPrivateKey(InputStream in) throws Exception {
        return loadPrivateKey(readKey(in));
    }

    private static String readKey(InputStream in) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String readLine = null;
        StringBuilder sb = new StringBuilder();
        while ((readLine = br.readLine()) != null) {
            if (readLine.charAt(0) == '-') {
                continue;
            } else {
                sb.append(readLine);
                sb.append('\r');
            }
        }

        return sb.toString();
    }

}
package com.netease.loan.bizmng;

import com.netease.loan.bizmng.common.utils.RSAUtils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.File;
import java.io.FileInputStream;
import java.security.PrivateKey;
import java.security.PublicKey;

/**
 * Created by hzliubenlong on 2017/5/13.
 */
public class RsaTest {
    public  static  void main(String[ ] asdfs) throws Exception {
        PublicKey publicKey = RSAUtils.loadPublicKey(new FileInputStream(new File("e://my_rsa_public_key_10.165.125.57.pem")));

        PrivateKey privateKey = RSAUtils.loadPrivateKey(new FileInputStream(new File("e://my_private_key.pem")));

        //加密
        String data = "{\"e\":\"sign_check_fail\",\"c\":2}";
        System.out.println(data);
        String encryptStr = (new BASE64Encoder()).encodeBuffer(RSAUtils.encryptData(data.getBytes(), publicKey));
        System.out.println(encryptStr);

        //解密
        System.out.println(new String(RSAUtils.decryptData((new BASE64Decoder()).decodeBuffer(encryptStr), privateKey)));


    }
}

运行结果

{"e":"sign_check_fail","c":2}
xReCIIU9+B5nS8hnPORKfTZZkDCXAeCaaJRjJUr0elcVnBHcQV1L5UXn/krJIY6EsjXlBurHKMrL
fHUOV0fbEfWZ/Ji/JDDTlx1ajPnEhbundCLHkGVBGaQsCv6eddH+dPJ2grH8xAqT/io6EFNWww5I
5SVpMVYAFlHQZPNB+60=

{"e":"sign_check_fail","c":2}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

快乐崇拜234

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

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

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

打赏作者

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

抵扣说明:

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

余额充值