当前位置: 首页 > 知识库问答 >
问题:

从文件中加载RSA公钥

柳项明
2023-03-14

我已生成一个私钥,其中包含:

openssl genrsa [-out file] –des3

在此之后,我生成了一个公钥:

openssl rsa –pubout -in private.key [-out file]

我想使用我的私钥对一些消息进行签名,并使用我的公钥验证一些其他消息,代码如下:

public String sign(String message) throws SignatureException{
    try {
        Signature sign = Signature.getInstance("SHA1withRSA");
        sign.initSign(privateKey);
        sign.update(message.getBytes("UTF-8"));
        return new String(Base64.encodeBase64(sign.sign()),"UTF-8");
    } catch (Exception ex) {
        throw new SignatureException(ex);
    }
}

public boolean verify(String message, String signature) throws SignatureException{
    try {
        Signature sign = Signature.getInstance("SHA1withRSA");
        sign.initVerify(publicKey);
        sign.update(message.getBytes("UTF-8"));
        return sign.verify(Base64.decodeBase64(signature.getBytes("UTF-8")));
    } catch (Exception ex) {
        throw new SignatureException(ex);
    }
}

我找到了一个将私钥转换为PKCS8格式并加载的解决方案。它适用于以下代码:

public PrivateKey getPrivateKey(String filename) throws Exception {

    File f = new File(filename);
    FileInputStream fis = new FileInputStream(f);
    DataInputStream dis = new DataInputStream(fis);
    byte[] keyBytes = new byte[(int) f.length()];
    dis.readFully(keyBytes);
    dis.close();
    PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory kf =
            KeyFactory.getInstance("RSA");
    return kf.generatePrivate(spec);
}

最后我的问题是:如何从文件中加载RSA公钥?

我想可能需要将公钥文件转换为x509格式,并使用X509EncodedKeySpec。但是我该怎么做呢?

共有3个答案

苏昊英
2023-03-14

一旦将密钥存储在PEM文件中,就可以使用BouncyCastle提供的PemObject和PemReader类轻松地将其读回,如本教程所示。

创建封装文件处理的PemFile类:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;

public class PemFile {

    private PemObject pemObject;

    public PemFile(String filename) throws FileNotFoundException, IOException {
        PemReader pemReader = new PemReader(new InputStreamReader(
                new FileInputStream(filename)));
        try {
            this.pemObject = pemReader.readPemObject();
        } finally {
            pemReader.close();
        }
    }

    public PemObject getPemObject() {
        return pemObject;
    }
}

然后像往常一样实例化私钥和公钥:

import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import org.apache.log4j.Logger;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class Main {

    protected final static Logger LOGGER = Logger.getLogger(Main.class);

    public final static String RESOURCES_DIR = "src/main/resources/rsa-sample/";

    public static void main(String[] args) throws FileNotFoundException,
            IOException, NoSuchAlgorithmException, NoSuchProviderException {
        Security.addProvider(new BouncyCastleProvider());
        LOGGER.info("BouncyCastle provider added.");

        KeyFactory factory = KeyFactory.getInstance("RSA", "BC");
        try {
            PrivateKey priv = generatePrivateKey(factory, RESOURCES_DIR
                    + "id_rsa");
            LOGGER.info(String.format("Instantiated private key: %s", priv));

            PublicKey pub = generatePublicKey(factory, RESOURCES_DIR
                    + "id_rsa.pub");
            LOGGER.info(String.format("Instantiated public key: %s", pub));
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
    }

    private static PrivateKey generatePrivateKey(KeyFactory factory,
            String filename) throws InvalidKeySpecException,
            FileNotFoundException, IOException {
        PemFile pemFile = new PemFile(filename);
        byte[] content = pemFile.getPemObject().getContent();
        PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(content);
        return factory.generatePrivate(privKeySpec);
    }

    private static PublicKey generatePublicKey(KeyFactory factory,
            String filename) throws InvalidKeySpecException,
            FileNotFoundException, IOException {
        PemFile pemFile = new PemFile(filename);
        byte[] content = pemFile.getPemObject().getContent();
        X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(content);
        return factory.generatePublic(pubKeySpec);
    }
}

希望这有帮助。

顾宸
2023-03-14

这个程序几乎用公共密钥和私钥做任何事情。der格式可以获得,但可以保存原始数据(无需编码bas64)。希望这对程序员有所帮助。

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import sun.security.pkcs.PKCS8Key;
import sun.security.pkcs10.PKCS10;
import sun.security.x509.X500Name;

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



/**
 * @author Desphilboy
 * DorOd bar shomA barobach
 *
 */
public class csrgenerator {

    private static PublicKey publickey= null;
    private static PrivateKey privateKey=null;
    //private static PKCS8Key privateKey=null;
    private static KeyPairGenerator kpg= null;
    private static ByteArrayOutputStream bs =null;
    private static csrgenerator thisinstance;
    private KeyPair keypair;
    private static PKCS10 pkcs10;
    private String signaturealgorithm= "MD5WithRSA";

    public String getSignaturealgorithm() {
        return signaturealgorithm;
    }



    public void setSignaturealgorithm(String signaturealgorithm) {
        this.signaturealgorithm = signaturealgorithm;
    }



    private csrgenerator() {
        try {
           kpg = KeyPairGenerator.getInstance("RSA");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            System.out.print("No such algorithm RSA in constructor csrgenerator\n");
        }
        kpg.initialize(2048);
        keypair = kpg.generateKeyPair();
        publickey = keypair.getPublic();
        privateKey = keypair.getPrivate();
    }



    /** Generates a new key pair 
    *
    * @param int bits 
    *   this is the number of bits in modulus must be 512, 1024, 2048  or so on 
    */
    public KeyPair generateRSAkys(int bits)
    {
          kpg.initialize(bits);
            keypair = kpg.generateKeyPair();
            publickey = keypair.getPublic();
            privateKey = keypair.getPrivate();
            KeyPair dup= keypair;
     return dup;
    }

     public static csrgenerator getInstance() {
            if (thisinstance == null)
                thisinstance = new csrgenerator();
            return thisinstance;
        }


     /**
      *  Returns a CSR as string  
      * @param cn  Common Name
      * @param OU  Organizational Unit 
      * @param Org  Organization
      * @param LocName Location name
      * @param Statename  State/Territory/Province/Region
      * @param Country    Country
      * @return     returns  csr as string.
      * @throws Exception
      */
     public String getCSR(String commonname, String organizationunit, String organization,String localname, String statename, String country ) throws Exception {
            byte[] csr = generatePKCS10(commonname, organizationunit, organization, localname, statename, country,signaturealgorithm);
            return new String(csr);
        }

     /** This function generates a new Certificate 
      * Signing Request. 
     *
     * @param CN
     *            Common Name, is X.509 speak for the name that distinguishes
     *            the Certificate best, and ties it to your Organization
     * @param OU
     *            Organizational unit
     * @param O
     *            Organization NAME
     * @param L
     *            Location
     * @param S
     *            State
     * @param C
     *            Country
     * @return    byte stream of generated request
     * @throws Exception
     */
    private static byte[] generatePKCS10(String CN, String OU, String O,String L, String S, String C,String sigAlg) throws Exception {
        // generate PKCS10 certificate request

        pkcs10 = new PKCS10(publickey);
       Signature   signature = Signature.getInstance(sigAlg);
        signature.initSign(privateKey);
        // common, orgUnit, org, locality, state, country
        //X500Name(String commonName, String organizationUnit,String organizationName,Local,State, String country)
        X500Name x500Name = new X500Name(CN, OU, O, L, S, C);
        pkcs10.encodeAndSign(x500Name,signature);
        bs = new ByteArrayOutputStream();
        PrintStream ps = new PrintStream(bs);
        pkcs10.print(ps);
        byte[] c = bs.toByteArray();
        try {
            if (ps != null)
                ps.close();
            if (bs != null)
                bs.close();
        } catch (Throwable th) {
        }
        return c;
    }

    public  PublicKey getPublicKey() {
        return publickey;
    }




    /**
     * @return
     */
    public PrivateKey getPrivateKey() {
        return privateKey;
    }

    /**
     * saves private key to a file
     * @param filename
     */
    public  void SavePrivateKey(String filename)
    {
        PKCS8EncodedKeySpec pemcontents=null;
        pemcontents= new PKCS8EncodedKeySpec( privateKey.getEncoded());
        PKCS8Key pemprivatekey= new  PKCS8Key( );
        try {
            pemprivatekey.decode(pemcontents.getEncoded());
        } catch (InvalidKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        File file=new File(filename);
        try {

            file.createNewFile();
            FileOutputStream fos=new FileOutputStream(file);
            fos.write(pemprivatekey.getEncoded());
            fos.flush();
            fos.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



    }



    /**
     * Saves Certificate Signing Request to a file;
     * @param filename  is a String containing full path to the file which will be created containing the CSR.
     */
    public void SaveCSR(String filename)
    {
        FileOutputStream fos=null;
        PrintStream ps=null;
        File file;
        try {

            file = new File(filename);
            file.createNewFile();
            fos = new FileOutputStream(file);
            ps= new PrintStream(fos);
        }catch (IOException e)
        {
            System.out.print("\n could not open the file "+ filename);
        }

        try {
            try {
                pkcs10.print(ps);
            } catch (SignatureException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            ps.flush();
            ps.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            System.out.print("\n cannot write to the file "+ filename);
            e.printStackTrace();

        }

        }


    /**
     * Saves both public key and private  key to file names specified
     * @param fnpub  file name of public key
     * @param fnpri  file name of private key
     * @throws IOException
     */
    public static void SaveKeyPair(String fnpub,String fnpri) throws IOException { 

// Store Public Key.
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(
publickey.getEncoded());
FileOutputStream fos = new FileOutputStream(fnpub);
fos.write(x509EncodedKeySpec.getEncoded());
fos.close();

// Store Private Key.
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded());
fos = new FileOutputStream(fnpri);
fos.write(pkcs8EncodedKeySpec.getEncoded());
fos.close();
}


    /**
     * Reads a Private Key from a pem base64 encoded file.
     * @param filename name of the file to read.
     * @param algorithm Algorithm is usually "RSA"
     * @return returns the privatekey which is read from the file;
     * @throws Exception
     */
    public  PrivateKey getPemPrivateKey(String filename, String algorithm) throws Exception {
          File f = new File(filename);
          FileInputStream fis = new FileInputStream(f);
          DataInputStream dis = new DataInputStream(fis);
          byte[] keyBytes = new byte[(int) f.length()];
          dis.readFully(keyBytes);
          dis.close();

          String temp = new String(keyBytes);
          String privKeyPEM = temp.replace("-----BEGIN PRIVATE KEY-----", "");
          privKeyPEM = privKeyPEM.replace("-----END PRIVATE KEY-----", "");
          //System.out.println("Private key\n"+privKeyPEM);

          BASE64Decoder b64=new BASE64Decoder();
          byte[] decoded = b64.decodeBuffer(privKeyPEM);

          PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decoded);
          KeyFactory kf = KeyFactory.getInstance(algorithm);
          return kf.generatePrivate(spec);
          }



    /**
     * Saves the private key to a pem file.
     * @param filename  name of the file to write the key into 
     * @param key the Private key to save.
     * @return  String representation of the pkcs8 object.
     * @throws Exception
     */
    public  String  SavePemPrivateKey(String filename) throws Exception {
        PrivateKey key=this.privateKey;
          File f = new File(filename);
          FileOutputStream fos = new FileOutputStream(f);
          DataOutputStream dos = new DataOutputStream(fos);


          byte[] keyBytes = key.getEncoded();
          PKCS8Key pkcs8= new PKCS8Key();
          pkcs8.decode(keyBytes);
          byte[] b=pkcs8.encode();

          BASE64Encoder b64=new BASE64Encoder();
          String  encoded = b64.encodeBuffer(b);

          encoded= "-----BEGIN PRIVATE KEY-----\r\n" + encoded + "-----END PRIVATE KEY-----";

         dos.writeBytes(encoded);
         dos.flush();
         dos.close();

          //System.out.println("Private key\n"+privKeyPEM);
        return pkcs8.toString();

          }


    /**
     * Saves a public key to a base64 encoded pem file
     * @param filename  name of the file 
     * @param key public key to be saved 
     * @return string representation of the pkcs8 object.
     * @throws Exception
     */
    public  String  SavePemPublicKey(String filename) throws Exception {
        PublicKey key=this.publickey;  
        File f = new File(filename);
          FileOutputStream fos = new FileOutputStream(f);
          DataOutputStream dos = new DataOutputStream(fos);


          byte[] keyBytes = key.getEncoded();
          BASE64Encoder b64=new BASE64Encoder();
          String  encoded = b64.encodeBuffer(keyBytes);

          encoded= "-----BEGIN PUBLIC KEY-----\r\n" + encoded + "-----END PUBLIC KEY-----";

         dos.writeBytes(encoded);
         dos.flush();
         dos.close();

          //System.out.println("Private key\n"+privKeyPEM);
      return  encoded.toString();

          }





       /**
     * reads a public key from a file
     * @param filename name of the file to read
     * @param algorithm is usually RSA
     * @return the read public key
     * @throws Exception
     */
    public  PublicKey getPemPublicKey(String filename, String algorithm) throws Exception {
          File f = new File(filename);
          FileInputStream fis = new FileInputStream(f);
          DataInputStream dis = new DataInputStream(fis);
          byte[] keyBytes = new byte[(int) f.length()];
          dis.readFully(keyBytes);
          dis.close();

          String temp = new String(keyBytes);
          String publicKeyPEM = temp.replace("-----BEGIN PUBLIC KEY-----\n", "");
          publicKeyPEM = publicKeyPEM.replace("-----END PUBLIC KEY-----", "");


          BASE64Decoder b64=new BASE64Decoder();
          byte[] decoded = b64.decodeBuffer(publicKeyPEM);

          X509EncodedKeySpec spec =
                new X509EncodedKeySpec(decoded);
          KeyFactory kf = KeyFactory.getInstance(algorithm);
          return kf.generatePublic(spec);
          }




    public static void main(String[] args) throws Exception {
        csrgenerator gcsr = csrgenerator.getInstance();
        gcsr.setSignaturealgorithm("SHA512WithRSA");
        System.out.println("Public Key:\n"+gcsr.getPublicKey().toString());

        System.out.println("Private Key:\nAlgorithm: "+gcsr.getPrivateKey().getAlgorithm().toString());
        System.out.println("Format:"+gcsr.getPrivateKey().getFormat().toString());
        System.out.println("To String :"+gcsr.getPrivateKey().toString());
        System.out.println("GetEncoded :"+gcsr.getPrivateKey().getEncoded().toString());
        BASE64Encoder encoder= new BASE64Encoder();
        String s=encoder.encodeBuffer(gcsr.getPrivateKey().getEncoded());
        System.out.println("Base64:"+s+"\n");

        String csr = gcsr.getCSR( "desphilboy@yahoo.com","baxshi az xodam", "Xodam","PointCook","VIC" ,"AU");
        System.out.println("CSR Request Generated!!");
        System.out.println(csr);
        gcsr.SaveCSR("c:\\testdir\\javacsr.csr");
        String p=gcsr.SavePemPrivateKey("c:\\testdir\\java_private.pem");
        System.out.print(p);
        p=gcsr.SavePemPublicKey("c:\\testdir\\java_public.pem");
        privateKey= gcsr.getPemPrivateKey("c:\\testdir\\java_private.pem", "RSA");
        BASE64Encoder encoder1= new BASE64Encoder();
        String s1=encoder1.encodeBuffer(gcsr.getPrivateKey().getEncoded());
        System.out.println("Private Key in Base64:"+s1+"\n");
        System.out.print(p);


    }

    }
须景胜
2023-03-14

以下是Zaki提供的链接中的相关信息。

生成2048位RSA私钥

$openssl genrsa-out私钥。pem 2048

将私钥转换为PKCS#8格式(以便Java能够读取)

$openssl pkcs8-topk8-通知PEM-输出DER-在私钥中。pem-输出私钥。der-nocrypt

以DER格式输出公钥部分(以便Java读取)

$openssl rsa-在私钥中。pem-pubout-输出公开密钥。der

私钥

import java.nio.file.*;
import java.security.*;
import java.security.spec.*;

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 java.nio.file.*;
import java.security.*;
import java.security.spec.*;

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);
  }
}
 类似资料:
  • 问题内容: 我用以下方法生成了一个私钥: 在此之后,我生成了一个公共密钥: 我想使用私钥对某些消息进行签名,并使用诸如此类的代码对其他私钥进行验证: 我找到了一种将私钥转换为PKCS8格式并加载它的解决方案。它可以与以下代码一起工作: 最后,我的问题是:如何从文件加载RSA公钥? 我认为也许我需要将我的公共密钥文件转换为x509格式,然后使用。但是我该怎么办呢? 问题答案: 下面是从相关信息的链接

  • 下面是我正在使用的代码 只要用要加密的文本调用'rsa'方法,就完成了。

  • 问题内容: 我正在为SAML 1.1断言消费者服务开发测试工具。测试必须生成签名的SAMLResponse,并将其提交给以Base64编码的ACS。ACS必须能够使用X509公共证书来验证签名的消息。 我能够构建SAMLResponse,添加必要的断言等。但是,当我尝试对对象进行签名时,我遇到了问题。这是我当前代码的一个片段: 错误发生在倒数第二行。我在控制台中看到以下内容: 尽管不是常规或安全的

  • 问题内容: 我正在尝试从java中的文件加载私钥。该密钥由ssh-agent生成。我实际上正在使用以下代码: 但是它产生了这个异常: 这是私钥: 有什么建议?谢谢。 问题答案: 您确定它是RSA吗?您还确定密钥的格式正确吗? 如果两个问题的答案都是肯定的,则可以尝试使用bouncycastle lib 编辑: 尝试从密钥中删除这些行: 更新:请 确保您的私钥为PKCS8格式,如果不需要,请按此处进

  • 问题内容: 在我的应用程序中,我生成一个公钥/私钥对,并将其存储以供以后在磁盘上使用。加载并重新初始化私钥可以正常工作,但是对于私钥,我得到了一个未知的KeySpec类型:java.security.spec.PKCS8EncodedKeySpec- 我不知道为什么。 这就是我创建和保存密钥的方式(简化了一些代码以便于阅读): 下次加载私钥可以正常工作: 公用密钥的类似代码惨遭失败: 那我在做什么

  • 我使用RSA_public_encrypt函数发送加密数据到套接字。我正在读取公钥。使用"pkey=PEM_read_PUBKEY(f, NULL, NULL, NULL);"函数的PEM文件。从上面的函数中检索的pkey是类型EVP_PKEY*,我不能在函数RSA_public_encrypt中使用。(RSA_public_encrypt使用RSA*类型密钥) 如何将EVP_PKEY*PKEY转