zoukankan      html  css  js  c++  java
  • Java读取pem格式公钥/私钥实现RSA加解密

    代码如下:

    生成.pem,这里使用2048位长度:

    openssl genrsa -out private_key.pem 1024
    

      

    将.pem转为.der:

    openssl pkcs8 -topk8 -inform PEM -outform DER -in private_key.pem -out private_key.der -nocrypt
    
    openssl rsa -in private_key.pem -pubout -outform DER -out public_key.der
    

      

    读取public_key.der:

    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.security.KeyFactory;
    import java.security.PublicKey;
    import java.security.spec.X509EncodedKeySpec;
    
    public class PublicKeyReader {
        public static PublicKey get(String filename) throws Exception {
            byte[] keyBytes = Files.readAllBytes(Paths.get(filename));
            X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
            KeyFactory kf = KeyFactory.getInstance("RSA");
            return kf.generatePublic(spec);
        }
    }
    

      

    读取private_key.der:

    import java.io.DataInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.security.KeyFactory;
    import java.security.PrivateKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    
    public class PrivateKeyReader {
        public static PrivateKey get(String filename) throws Exception {
            byte[] keyBytes = Files.readAllBytes(Paths.get(filename));
            PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory kf = KeyFactory.getInstance("RSA");
            return kf.generatePrivate(spec);
        }
    }
    

      

    测试:

    import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;
    
    import java.io.IOException;
    import java.nio.charset.StandardCharsets;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    
    public class RSAReadKeyTest {
        public static void main(String[] args) throws Exception {
            String text = "When and where
    " +
                    "Join us on June 25, 2020 10:00 Pacific Daylight Time. The workshops will be livestreamed to YouTube via Google Cloud Platform in partnership with AI Huddle.
    " +
                    "
    " +
                    "Is this for me?
    " +
                    "This session is especially geared for professional working data scientists. You should be comfortable with Python to build machine or deep learning models. If you’re curious how accelerators can improve your workflow, this is for you!
    " +
                    "
    " +
                    "Agenda
    " +
                    "Session 1: 10:00-10:30 AM PDT
    " +
                    "Compete in a Kaggle Competition Using TensorFlow GPUs with Chris Deotte 
    " +
                    "“Follow along as I make a simple notebook from my team's Gold medal solution to Bengali Handwriting Classification competition.”
    " +
                    "
    " +
                    "Session 2: 10:30-11:00 AM PDT 
    " +
                    "Approach (Almost) Any Deep Learning Problem Using PyTorch and TPUs with Abhishek Thakur
    " +
                    "“Allow me to show you how to harness the power of TPUs and Pytorch to quickly train almost any model!”";
    
            PublicKey pubKey = PublicKeyReader.get("src/gj/secure/rsa_public_key.der");
            byte[] bytes = RSAUtil.encryptByPublicKey(pubKey, text.getBytes());
            String cipherText = toBase64(bytes);
            System.out.println(cipherText);
    
            PrivateKey priKey = PrivateKeyReader.get("src/gj/secure/rsa_private_key.der");
            byte[] cipherBytes = fromBase64(cipherText);
            byte[] result = RSAUtil.decryptByPrivateKey(priKey, cipherBytes);
            System.out.println(new String(result, StandardCharsets.UTF_8));
        }
    
        public static String toBase64(byte[] bytes) {
            return new BASE64Encoder().encode(bytes);
        }
    
        public static byte[] fromBase64(String b64String) throws IOException {
            return new BASE64Decoder().decodeBuffer(b64String);
        }
    }
    

     

    附RSAUtil.java代码:

    import javax.crypto.Cipher;
    import java.io.ByteArrayOutputStream;
    import java.security.*;
    
    /**
     * @author areful
     * Date: 2019/2/12
     */
    public class RSAUtil {
        public static final String ALGORITHM_RSA = "RSA";
        public static final String ALGORITHM_RSA_PKCS1PADDING = "RSA/ECB/PKCS1PADDING";
        public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
        private static final int MAX_ENCRYPT_BLOCK = 117;
        private static final int MAX_DECRYPT_BLOCK = 128;
    
        public static KeyPair genKeyPair() throws Exception {
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(ALGORITHM_RSA);
            keyPairGen.initialize(1024);
            return keyPairGen.generateKeyPair();
        }
    
        public static byte[] encryptByPublicKey(PublicKey pubKey, byte[] data) throws Exception {
            return doFinal(pubKey, Mode.ENCRYPT, data);
        }
    
        public static byte[] decryptByPrivateKey(PrivateKey priKey, byte[] data) throws Exception {
            return doFinal(priKey, Mode.DECRYPT, data);
        }
    
        public static byte[] encryptByPrivateKey(PrivateKey priKey, byte[] data) throws Exception {
            return doFinal(priKey, Mode.ENCRYPT, data);
        }
    
        public static byte[] decryptByPublicKey(PublicKey pubKey, byte[] data) throws Exception {
            return doFinal(pubKey, Mode.DECRYPT, data);
        }
    
        public static byte[] sign(PrivateKey priKey, byte[] data) throws Exception {
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            signature.initSign(priKey);
            signature.update(data);
            return signature.sign();
        }
    
        public static boolean verify(PublicKey pubKey, byte[] data, byte[] sign) throws Exception {
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            signature.initVerify(pubKey);
            signature.update(data);
            return signature.verify(sign);
        }
    
        private enum Mode {
            ENCRYPT(Cipher.ENCRYPT_MODE),
            DECRYPT(Cipher.DECRYPT_MODE);
            private final int value;
    
            Mode(int value) {
                this.value = value;
            }
        }
    
        private static byte[] doFinal(Key key, Mode mode, byte[] data) throws Exception {
            final int MAX = (mode == Mode.ENCRYPT) ? MAX_ENCRYPT_BLOCK : MAX_DECRYPT_BLOCK;
            final int LEN = data.length;
            byte[] cache;
            int i = 0, off = 0;
    
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            Cipher cipher = Cipher.getInstance(ALGORITHM_RSA_PKCS1PADDING);
            cipher.init(mode.value, key);
            while (off < LEN) {
                cache = cipher.doFinal(data, off, Math.min(LEN - off, MAX));
                out.write(cache, 0, cache.length);
                i++;
                off = i * MAX;
            }
            byte[] result = out.toByteArray();
            out.close();
            return result;
        }
    }
    

      

    附RSAUtil.java测试代码:

    import java.security.KeyPair;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.util.Arrays;
    
    public class RSATest {
        public static void main(String[] args) throws Exception {
            KeyPair keyPair = RSAUtil.genKeyPair();
            PublicKey publicKey = keyPair.getPublic();
            PrivateKey privateKey = keyPair.getPrivate();
    
            System.err.println("公钥加密——私钥解密");
            String src = "第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。";
            System.out.println("原文字:	" + src);
            byte[] encodedData = RSAUtil.encryptByPublicKey(publicKey, src.getBytes());
            System.out.println("加密后:	" + Arrays.toString(encodedData));
            String plainText = new String(RSAUtil.decryptByPrivateKey(privateKey, encodedData));
            System.out.println("解密后: 	" + plainText);
    
            System.err.println("私钥加密——公钥解密");
            System.out.println("原文字:	" + src);
            encodedData = RSAUtil.encryptByPrivateKey(privateKey, src.getBytes());
            System.out.println("加密后:	" + Arrays.toString(encodedData));
            plainText = new String(RSAUtil.decryptByPublicKey(publicKey, encodedData));
            System.out.println("解密后: 	" + plainText);
    
            System.err.println("私钥签名——公钥验证签名");
            byte[] sign = RSAUtil.sign(privateKey, encodedData);
            System.err.println("签名:		" + Arrays.toString(sign));
            boolean status = RSAUtil.verify(publicKey, encodedData, sign);
            System.err.println("验证结果:	" + status);
        }
    }
    

     

    Thanks to:https://stackoverflow.com/questions/11410770/load-rsa-public-key-from-file

  • 相关阅读:
    编程语言的精髓
    进销存-库存表-算法
    JAVA 将JSON数组转化成JAVA数组
    使input文本框不可编辑的3种方法
    如何让一个DIV固定在另一个DIV的底部
    错误笔记既 onclick()事件写方法传jstl表达式作为变量
    错误笔记
    SQL查询语句左连接
    查已有表的建表语句
    使用(文件上传域)MultipartFile接受文件时的判空方式
  • 原文地址:https://www.cnblogs.com/areful/p/13156412.html
Copyright © 2011-2022 走看看