使用RSA生成公钥和私钥

这篇具有很好参考价值的文章主要介绍了使用RSA生成公钥和私钥。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.jdk keytool

可以用keytool工具直接生成,需要openssl工具Binaries - OpenSSLWiki设置到环境变量里

@echo off
cd ../output
IF exist auth.jks del auth.jks
IF exist auth.key del auth.key
keytool -genkeypair -alias xxxx_key -keyalg RSA -keypass xxxxxx -keystore auth.jks -storepass xxxxxx -dname CN=xxx
keytool -list -rfc --keystore auth.jks -storepass xxxxxx | openssl x509 -inform pem -pubkey > temp.key
(@FOR /f "tokens=1* delims=:" %%a IN ('findstr /n "^" "temp.key"') DO @IF %%a leq 9 ECHO(%%b) > auth.key
del temp.key
echo Build OK!
pause

 2.认证与鉴权使用

生成的authkey放到gateway下,生成的auth.jks放到auth认证服务下

网关结合鉴权,需要配置如下配置文件                

spring:
    security:
        oauth2:
            resourceserver:
                jwt:
                    public-key-location: classpath:auth.key

认证服务配置Bean

    @Bean
    public JWKSource<SecurityContext> jwkSource() throws Exception {

        KeyStore keyStore = KeyStore.getInstance("JKS");
        // 取得JKS文件
        Resource resource = new ClassPathResource(DEFAULT_KEY_STORE_FILE);
        if (!resource.exists()) {
            resource = new FileSystemResource(DEFAULT_KEY_STORE_FILE);
        }
        try (InputStream inputStream = resource.getInputStream()) {
            keyStore.load(inputStream, DEFAULT_KEY_STORE_PASSWORD.toCharArray());
            RSAPublicKey publicKey = (RSAPublicKey) keyStore.getCertificate(DEFAULT_KEY_ALIAS).getPublicKey();
            RSAPrivateKey privateKey = (RSAPrivateKey) keyStore.getKey(DEFAULT_KEY_ALIAS, DEFAULT_KEY_PASSWORD.toCharArray());
            RSAKey rsaKey = new RSAKey.Builder(publicKey)
                    .privateKey(privateKey)
                    .keyStore(keyStore)
                    .build();
            JWKSet jwkSet = new JWKSet(rsaKey);
            return new ImmutableJWKSet<>(jwkSet);
        }
    }

3.工程项目直接生成

接口AuthToolController

package xxx.authtool.controller;

import xxx.authtool.util.RsaUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.security.KeyPair;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@RestController
@RequestMapping("/generate")
public class AuthToolController {

    @Value("${file-path:}")
    private String filePath;

    /**
     * 创建并下载auth.key和auth.jks
     * @param days 创建证书的有效期 单位:天 不传默认90天
     * @param response http返回值
     * @throws IOException 异常
     */
    @GetMapping("/downloadAuthKeyZip")
    public void downloadAuthKeyZip(@RequestParam(required = false) Integer days, HttpServletResponse response) throws IOException {

        String dirPath = mkdir();
        // 创建一个临时zip文件,用于存放要下载的多个文件
        File zipFile = new File(dirPath + "/" + "authKeys.zip");

        // 获取需要下载的多个文件,并将它们添加到zip文件中
        List<File> filesToDownload = getFilesToDownload(dirPath, days);
        addFilesToZip(filesToDownload, zipFile);
        deleteFiles(filesToDownload);

        //设置响应头信息
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename=authKeys.zip");

        // 将zip文件内容写入到HttpServletResponse输出流中,实现文件下载
        try (InputStream inputStream = Files.newInputStream(zipFile.toPath());
             OutputStream outputStream = response.getOutputStream()) {
            byte[] buffer = new byte[4096];
            int length;
            while ((length = inputStream.read(buffer)) > 0) {
                outputStream.write(buffer, 0, length);
                outputStream.flush();
            }
        }
    }

    /**
     * 删除文件
     * @param filesToDownload 文件列表
     */
    private void deleteFiles(List<File> filesToDownload) {
        for (File file : filesToDownload) {
            file.delete();
        }
    }

    /**
     * 获取文件列表
     * @param dirPath 文件路径
     * @param days 时间
     * @return 文件列表
     */
    private List<File> getFilesToDownload(String dirPath, Integer days) {
        // 获取需要下载的多个文件
        List<File> files = new ArrayList<>();
        KeyPair keyPair = RsaUtil.genKeyPair();

        File publicFile = RsaUtil.genPublicFile(keyPair, dirPath);
        File privateFile = RsaUtil.genPrivateFile(keyPair, dirPath, days);

        files.add(publicFile);
        files.add(privateFile);
        return files;
    }


    /**
     * 压缩文件
     * @param filesToDownload 文件列表
     * @param zipFile 压缩文件
     * @throws IOException 异常
     */
    private void addFilesToZip(List<File> filesToDownload, File zipFile) throws IOException {
        // 将多个文件压缩到zip文件中
        try (ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(zipFile.toPath()))) {
            for (File file : filesToDownload) {
                zipOutputStream.putNextEntry(new ZipEntry(file.getName()));
                try (FileInputStream inputStream = new FileInputStream(file)) {
                    byte[] buf = new byte[1024];
                    int len;
                    while ((len = inputStream.read(buf)) > 0) {
                        zipOutputStream.write(buf, 0, len);
                    }
                }
                zipOutputStream.closeEntry();
            }
        }
    }

    /**
     * 创建文件夹
     * @return 文件路径
     */
    private String mkdir() {
        String dateString = getDateString();
        // 文件夹路径
        String dirPath = filePath + "/" + dateString;

        File directory = new File(dirPath);
        // 判断文件夹是否存在
        if (!directory.exists()) {
            // 创建文件夹及其父目录
            directory.mkdirs();
        }
        return dirPath;
    }


    /**
     * 获取日期字符串
     * @return 日期字符串
     */
    private String getDateString() {
        Date currentDate = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
        return dateFormat.format(currentDate);
    }
}

RSAUtil

package xxx.authtool.util;

import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import sun.security.x509.X500Name;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.util.Date;

/**
 * RSA工具类
 *
 * @author xxx
 */
public final class RsaUtil {

    public static final String DEFAULT_KEY_STORE_FILE = "auth.jks";
    public static final String DEFAULT_KEY_FILE = "auth.key";

    public static final String DEFAULT_KEY_STORE_PASSWORD = "xxxxxx";

    public static final String DEFAULT_KEY_ALIAS = "xxxx";

    public static final String DEFAULT_KEY_PASSWORD = "xxxxxx";


    /**
     * 随机生成密钥对
     */
    public static KeyPair genKeyPair() {
        try {
            // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
            // 初始化密钥对生成器,密钥大小为96-1024位
            keyPairGen.initialize(2048, new SecureRandom());
            // 生成一个密钥对,保存在keyPair中
            return keyPairGen.generateKeyPair();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 生成私钥
     * @param keyPair 密钥对
     * @param dirPath 文件列表
     * @param days 时间
     * @return 秘钥文件
     */
    public static File genPrivateFile(KeyPair keyPair, String dirPath, Integer days) {
        File file = new File(dirPath + "/" + DEFAULT_KEY_STORE_FILE);
        try (FileOutputStream fos = new FileOutputStream(file)) {
            KeyStore keyStore = KeyStore.getInstance("JKS");

            keyStore.load(null, DEFAULT_KEY_PASSWORD.toCharArray());
            // 得到私钥
            PrivateKey privateKey = keyPair.getPrivate();
            // 为以下对象生成 2048 位RSA密钥对和自签名证书 (SHA256withRSA) (有效期为 90 天):
            String dn = "CN=xxxx";
            // 有效期默认为 90 天
            int day = 90;
            if (days != null) {
                day = days;
            }
            X509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(
                    new X500Name(dn).asX500Principal(),
                    BigInteger.valueOf(System.currentTimeMillis()),
                    new Date(System.currentTimeMillis()),
                    new Date(System.currentTimeMillis() + day * 24 * 60 * 60 * 1000L),
                    new X500Name(dn).asX500Principal(),
                    keyPair.getPublic());

            ContentSigner signer =
                    new JcaContentSignerBuilder("SHA256withRSA").setProvider(new BouncyCastleProvider()).build(keyPair.getPrivate());

            Certificate cert = new JcaX509CertificateConverter().setProvider(new BouncyCastleProvider()).getCertificate(builder.build(signer));

            keyStore.setKeyEntry(DEFAULT_KEY_ALIAS, privateKey, DEFAULT_KEY_PASSWORD.toCharArray(), new Certificate[]{cert});

            keyStore.store(fos, DEFAULT_KEY_STORE_PASSWORD.toCharArray());
            return file;
        } catch (KeyStoreException | IOException | CertificateException | NoSuchAlgorithmException |
                 OperatorCreationException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 生成公钥文件
     * @param keyPair 密钥对
     * @param dirPath 文件列表
     * @return 公钥文件
     */
    public static File genPublicFile(KeyPair keyPair, String dirPath) {
        try (StringWriter sw = new StringWriter()) {
            // 得到公钥
            PublicKey publicKey = keyPair.getPublic();
            // 获取PublicKey并将其转换为PEM格式的字符串
            try (JcaPEMWriter pemWriter = new JcaPEMWriter(sw)) {
                pemWriter.writeObject(publicKey);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            File file = new File(dirPath + "/" + DEFAULT_KEY_FILE);

            try (FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);
                 BufferedWriter bw = new BufferedWriter(fw)
            ) {
                bw.write(sw.toString());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return file;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

依赖

	implementation 'org.bouncycastle:bcprov-jdk15on:1.69'
	implementation 'org.bouncycastle:bcpkix-jdk15on:1.69'

访问localhost:6080/generate/downloadAuthKeyZip可获取90天许可的证书

4.RSA工具类

package xxx.socket.stomp.config;

import java.nio.charset.StandardCharsets;
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.SecureRandom;
import java.security.spec.EncodedKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.springframework.util.Assert;

/**
 * RSA工具类
 *
 */
public class RsaUtils {

    private static String publicKeyStr = "";
    private static String privateKeyStr = "";

    public static void main(String[] args) {

        genKeyPair();

        String password = "xxxx";
        String rawPassword = encrypt(password);
        String password2 = decrypt(rawPassword);
        Assert.isTrue(password.equals(password2), "Error");
    }

    public static String encrypt(String password) {
        try {
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyStr));
            PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);

            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] passwordBytes = cipher.doFinal(password.getBytes(StandardCharsets.UTF_8));
            String result = new String(Base64.getEncoder().encode(passwordBytes), StandardCharsets.UTF_8);
            System.out.println("Encrypt Password: " + result);
            return result;
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            System.out.println("Algorithm Error\n" + e);
        } catch (NoSuchPaddingException | InvalidKeyException e) {
            System.out.println("Cipher Error\n" + e);
        } catch (IllegalBlockSizeException | BadPaddingException e) {
            System.out.println("Password Error\n" + e);
        }
        return null;
    }

    public static String decrypt(String password) {
        try {
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyStr));
            PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);

            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] passwordBytes = cipher.doFinal(Base64.getDecoder().decode(password.getBytes(StandardCharsets.UTF_8)));
            String result = new String(passwordBytes, StandardCharsets.UTF_8);
            System.out.println("Decrypt Password: " + result);
            return result;
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            System.out.println("Algorithm Error\n" + e);
        } catch (NoSuchPaddingException | InvalidKeyException e) {
            System.out.println("Cipher Error\n" + e);
        } catch (IllegalBlockSizeException | BadPaddingException e) {
            System.out.println("Password Error\n" + e);
        }
        return null;
    }

    /**
     * 随机生成密钥对
     */
    public static void genKeyPair() {
        try {
            // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
            // 初始化密钥对生成器,密钥大小为96-1024位
            keyPairGen.initialize(2048, new SecureRandom());
            // 生成一个密钥对,保存在keyPair中
            KeyPair keyPair = keyPairGen.generateKeyPair();
            // 得到私钥
            PrivateKey privateKey = keyPair.getPrivate();
            // 得到公钥
            PublicKey publicKey = keyPair.getPublic();

            String publicKeyString = new String(Base64.getEncoder().encode(publicKey.getEncoded()));
            // 得到私钥字符串
            String privateKeyString = new String(Base64.getEncoder().encode((privateKey.getEncoded())));
            System.out.println("随机生成的公钥为:" + publicKeyString);
            System.out.println("随机生成的私钥为:" + privateKeyString);
            publicKeyStr = publicKeyString;
            privateKeyStr = privateKeyString;
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }
}

5. 参考资料

www.php1.cn/detail/Java_ShiYong_key_81410199.html文章来源地址https://www.toymoban.com/news/detail-524529.html

到了这里,关于使用RSA生成公钥和私钥的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • RSA双向加解密(公钥加密-私钥解密;私钥加密-公钥解密)

            非对称加密算法中,提供一个公钥一个私钥。一般情况下,采用公钥加密、私钥解密的方式。         假设有这样一个场景:服务A与服务B需要通信,通信内容为了安全需要进行加密传输,并且服务A与服务B不能互相持有对方的钥匙。         我首先想到的是

    2024年02月11日
    浏览(67)
  • Java RSA加解密-非对称加密-公钥私钥加解密(使用hutool工具)

    之前一篇帖子(https://blog.csdn.net/u014137486/article/details/136413532)展示了使用原生Java进行RSA加解密,本文介绍下使用当下流行的Hutool工具进行RSA加解密的用法。 目录 一、在Linux环境下生成公钥、私钥文件 二、将生成的公私钥文件导入项目中并移除pem文件的前后公私钥标记 三、po

    2024年04月23日
    浏览(105)
  • Windows生成公钥和私钥

    如果没有.ssh文件夹,解决办法参考如下 https://blog.csdn.net/m0_53721382/article/details/128666297 注:可以使用cmder软件查看公钥内容(cmder的命令和linux一样) 注:cmder添加到右键的方法,在Windows下使用管理员身份运行cmd,然后执行下列命令即可看到右键菜单中多了cmder here

    2024年02月16日
    浏览(60)
  • openssl3.2 - 检查rsa证书和私钥是否匹配(快速手搓一个工具)

    在学习openssl官方的/test/certs的脚本实现, 做到第30个脚本实验时, 发现根CA证书和key不匹配. 估计做实验时, 遇到脚本需要的文件, 就随便拷贝一个同名的文件过来, 导致证书和key不是一个脚本产生的, 所以不匹配 就想从前面的实验中, 找出匹配的证书和key来做实验, 肯定有啊. 这事

    2024年01月24日
    浏览(64)
  • C#.NET Framework RSA 公钥加密 私钥解密 ver:20230609

    C#.NET Framework RSA 公钥加密 私钥解密 ver:20230609   环境说明: .NET Framework 4.6 的控制台程序 。   .NET Framework 对于RSA的支持: 1. .NET Framework 内置只支持XML格式的私钥/公钥。如果要用PKCS1,PKCS8格式的,要用到三方库BouncyCastle。 2. .NET 中默认加密算法为“RSA/ECB/PKCS1Padding” ,要和

    2024年02月08日
    浏览(72)
  • 已知RSA的公钥(e,n)计算对应的私钥d

    今天分享一个软考中经常出现的关于RSA私钥计算的题目。我们试着理解背后的算法逻辑,然后再看看如何解题。 设在RSA的公钥密码体制中,公钥为(e, n)= (13, 35), 则私钥d= ()。  A. 17 B. 15 C. 13 D. 11 Rivest Shamir Adleman(RSA)加密算法是一种非对称加密算法,广泛应用于许多产

    2023年04月18日
    浏览(46)
  • C# .NET CORE .NET6 RSA 公钥加密 私钥解密

    环境说明: .NET CORE 版本:.NET 6 。   .NET CORE 对于RSA的支持: 1. .NET 6 中内置了对 PKCS1,PKCS8 2种私钥格式的支持。 2. 如果你要部署在Linux,docker ,k8s 中;一定要用 “RSA”这个类,不能是 .NET FRAMEWORK 的 RSACryptoServiceProvider。 3. .NET 中默认加密算法为“RSA/ECB/PKCS1Padding” ,要和JAVA互通

    2024年02月08日
    浏览(94)
  • RSA加解密工具类(PKCS8公钥加密,PKCS1私钥解密)

    场景 :如果项目上生成的秘钥,公钥是PKCS8格式,私钥却是PKCS1格式。需要在这种场景加解密的话可以直接使用下面工具类。 特殊说明:私钥解密的时候必须把私钥源文件内容整个传入,不能删除私钥的文件头和文件尾,并且不能删除换行。

    2024年02月11日
    浏览(67)
  • 使用 OpenSSL 扩展来实现公钥和私钥加密

    首先,你需要生成一对公钥和私钥。可以使用 OpenSSL 工具来生成: 1、生成私钥 2、从私钥生成公钥: 现在你有了一个私钥( private_key.pem )和一个对应的公钥( public_key.pem )。下面是如何在 PHP 中使用它们进行加密和解密: 3、检测是否支付OPENSSL,或用phpinfo(); 上述代码中,

    2024年02月03日
    浏览(59)
  • jdk 中的 keytool 的使用,以及提取 jks 文件中的公钥和私钥

    这里暂时只需要知道如何使用就可以了。 首先是生成一个密钥, 解释一下这里的选项, -alias 密钥对的名称 -keypass 密钥密码 -validity 有效期,这里是以天为单位 -storepass 存储库的密码 -keystore 指定生成的密钥文件存放的位置,这里的  fanyfull.jks  表示的是当前目录下的  fan

    2024年02月08日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包