非对称加密 公钥私钥

抽象

这是涵盖Java加密算法的三部分博客系列的第3部分。 该系列涵盖如何实现以下功能:

  1. 使用SHA–512散列
  2. 使用AES–256的单密钥对称加密
  3. RSA–4096

这第三篇文章详细介绍了如何实现非对称的RSA-4096公/私钥加密。 让我们开始吧。

免责声明

这篇文章仅供参考。 在使用所提供的任何信息之前,请认真思考。 从中学到东西,但最终自己做出决定,风险自负。

要求

我使用以下主要技术完成了本文的所有工作。 您可能可以使用不同的技术或版本来做相同的事情,但不能保证。

  • Java 1.8.0_152_x64
  • NetBeans 8.2(内部版本201609300101)
  • Maven 3.0.5(与NetBeans捆绑在一起)

下载

访问我的GitHub页面以查看我所有的开源项目。 这篇文章的代码位于项目中: thoth-cryptography

非对称加密

关于

非对称算法基于两个密钥:公钥和私钥。 公钥负责加密,私钥负责解密。 公用密钥可以自由分发。 使用公共密钥,任何客户端都可以加密一条消息,只有您(使用私有密钥)可以解密该消息(非对称算法,第3段)。

非对称算法是Internet的主力军。 像SSH,OpenPGP,SSL和TLS之类的协议依赖于非对称算法(Rouse,2016,第2段)。 使用网络浏览器进行在线银行之类的工作的人都固有地知道非对称算法的重要性。

截止目前的研究似乎表明,以下是最佳和最安全的公钥/私钥,非对称加密算法(Sheth,2017年,“选择正确的算法”,第2段):

  1. 算法: RSA
  2. 模式: ECB //确实没有,但是需要ECB才能使Java工作。
  3. 填充: OAEPWithSHA–512AndMGF1Padding
  4. 密钥大小: 4096位

RSA不是分组密码,因此ECB模式没有多大意义,但是,即使未在内部使用该模式,也需要ECB来使Java工作(Brightwell,2015年)。 OAEP提供了高度的随机性和填充性。 让我们看一个例子。

清单1是RsaTest.java单元测试。 这是以下内容的完整演示:

  1. 生成并存储RSA 4096位密钥
  2. RSA加密
  3. RSA解密

清单2显示了RsaKeyPairProducer.java 。 这是一个帮助程序类,负责产生一个新的KeyPairKeyPair对同时包含PublicKeyPrivateKey
清单3显示了RsaPrivateKeyProducer.java 。 这是一个帮助程序类,负责从byte[]再现专用PrivateKey

清单4显示了RsaPublicKeyProducer.java 。 这是一个帮助程序类,负责从byte[]复制PublicKey

清单5显示了ByteArrayWriter.java ,清单6显示了ByteArrayReader.java 。 这些是负责将byte[]写入文件的助手类。 由您决定如何存储密钥的byte[] ,但需要将其安全地存储在某个地方(文件,数据库,git存储库等)。

清单7显示了RsaEncrypter.java 。 这是一个负责加密的助手类。

最后,清单8显示了RsaDecrypter.java 。 这是一个负责解密的助手类。

清单1 – RsaTest.java类

package org.thoth.crypto.asymmetric;import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.thoth.crypto.io.ByteArrayReader;
import org.thoth.crypto.io.ByteArrayWriter;/**** @author Michael Remijan mjremijan@yahoo.com @mjremijan*/
public class RsaTest {static Path privateKeyFile;static Path publicKeyFile;@BeforeClasspublic static void beforeClass() throws Exception {// Store the PrivateKey and PublicKey bytes in the ./target// diretory. Do this so it will be ignore by source control.// We don't want this file committed.privateKeyFile= Paths.get("./target/RsaPrivate.key").toAbsolutePath();publicKeyFile= Paths.get("./target/RsaPublic.key").toAbsolutePath();// Create KeyPair for RSAKeyPair keyPair= new RsaKeyPairProducer().produce();// Store the PrivateKey bytes. This is what// you want to keep absolutely safe{ByteArrayWriter writer = new ByteArrayWriter(privateKeyFile);writer.write(keyPair.getPrivate().getEncoded());}// Store the PublicKey bytes.  This you// can freely distribute so others can// encrypt messages which you can then// decrypt with the PrivateKey you keep safe.{ByteArrayWriter writer = new ByteArrayWriter(publicKeyFile);writer.write(keyPair.getPublic().getEncoded());}}@Testpublic void encrypt_and_decrypt() throws Exception {// setupPrivateKey privateKey= new RsaPrivateKeyProducer().produce(new ByteArrayReader(privateKeyFile).read());PublicKey publicKey= new RsaPublicKeyProducer().produce(new ByteArrayReader(publicKeyFile).read());RsaDecrypter decrypter= new RsaDecrypter(privateKey);RsaEncrypter encrypter= new RsaEncrypter(publicKey);String toEncrypt= "encrypt me";// runbyte[] encryptedBytes= encrypter.encrypt(toEncrypt);System.out.printf("Encrypted %s%n", new String(encryptedBytes,"UTF-8"));String decrypted= decrypter.decrypt(encryptedBytes);// assertAssert.assertEquals(toEncrypt, decrypted);}}

清单2 – RsaKeyPairProducer.java类

package org.thoth.crypto.asymmetric;import java.security.KeyPair;
import java.security.KeyPairGenerator;/**** @author Michael Remijan mjremijan@yahoo.com @mjremijan*/
public class RsaKeyPairProducer {/*** Generates a new RSA-4096 bit {@code KeyPair}.** @return {@code KeyPair}, never null* @throws RuntimeException All exceptions are caught* and re-thrown as {@code RuntimeException}*/public KeyPair produce() {KeyPairGenerator keyGen;try {keyGen = KeyPairGenerator.getInstance("RSA");//keyGen.initialize(3072);keyGen.initialize(4096);return keyGen.generateKeyPair();} catch (Exception ex) {throw new RuntimeException(ex);}}
}

清单3 – RsaPrivateKeyProducer.java类

package org.thoth.crypto.asymmetric;import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;/**** @author Michael Remijan mjremijan@yahoo.com @mjremijan*/
public class RsaPrivateKeyProducer {/*** Regenerates a previous RSA {@code PrivateKey}.** @param encodedByteArrayForPrivateKey The bytes this method* will use to regenerate a previously created {@code PrivateKey}** @return {@code PrivateKey}, never null* @throws RuntimeException All exceptions are caught* and re-thrown as {@code RuntimeException}*/public PrivateKey produce(byte[] encodedByteArrayForPrivateKey) {try {PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(encodedByteArrayForPrivateKey));return privateKey;} catch (Exception ex) {throw new RuntimeException(ex);}}
}

清单4 – RsaPublicKeyProducer.java类

package org.thoth.crypto.asymmetric;import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;/**** @author Michael Remijan mjremijan@yahoo.com @mjremijan*/
public class RsaPublicKeyProducer {/*** Regenerates a previous RSA {@code PublicKey}.** @param encodedByteArrayForPublicKey The bytes this method* will use to regenerate a previously created {@code PublicKey}** @return {@code PublicKey}, never null* @throws RuntimeException All exceptions are caught* and re-thrown as {@code RuntimeException}*/public PublicKey produce(byte[] encodedByteArrayForPublicKey) {try {PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(encodedByteArrayForPublicKey));return publicKey;} catch (Exception ex) {throw new RuntimeException(ex);}}
}

清单5 – ByteArrayWriter.java类

package org.thoth.crypto.io;import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;/**** @author Michael Remijan mjremijan@yahoo.com @mjremijan*/
public class ByteArrayWriter {protected Path outputFile;private void initOutputFile(Path outputFile) {this.outputFile = outputFile;}private void initOutputDirectory() {Path outputDirectory = outputFile.getParent();if (!Files.exists(outputDirectory)) {try {Files.createDirectories(outputDirectory);} catch (IOException e) {throw new RuntimeException(e);}}}public ByteArrayWriter(Path outputFile) {initOutputFile(outputFile);initOutputDirectory();}public void write(byte[] bytesArrayToWrite) {try (OutputStream os= Files.newOutputStream(outputFile);PrintWriter writer=  new PrintWriter(os);){for (int i=0; i<bytesArrayToWrite.length; i++) {if (i>0) {writer.println();}writer.print(bytesArrayToWrite[i]);}} catch (IOException ex) {throw new RuntimeException(ex);}}
}

清单6 – ByteArrayReader.java类

package org.thoth.crypto.io;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Scanner;/**** @author Michael Remijan mjremijan@yahoo.com @mjremijan*/
public class ByteArrayReader {protected Path inputFile;public ByteArrayReader(Path inputFile) {this.inputFile = inputFile;}public byte[] read() {try (Scanner scanner=  new Scanner(inputFile);ByteArrayOutputStream baos= new ByteArrayOutputStream();){while (scanner.hasNext()) {baos.write(Byte.parseByte(scanner.nextLine()));}baos.flush();return baos.toByteArray();} catch (IOException ex) {throw new RuntimeException(ex);}}
}

清单7 – RsaEncrypter.java类

package org.thoth.crypto.asymmetric;import java.security.PublicKey;
import javax.crypto.Cipher;/**** @author Michael Remijan mjremijan@yahoo.com @mjremijan*/
public class RsaEncrypter {protected RsaCipher cipher;public RsaEncrypter(PublicKey key) {this.cipher = new RsaCipher(Cipher.ENCRYPT_MODE, key);}public byte[] encrypt(String message) {try {return cipher.update(message.getBytes("UTF-8")).doFinal();} catch (Exception e) {throw new RuntimeException(e);}}
}

清单8 – RsaDecrypter.java类

package org.thoth.crypto.asymmetric;import java.security.PrivateKey;
import javax.crypto.Cipher;/**** @author Michael Remijan mjremijan@yahoo.com @mjremijan*/
public class RsaDecrypter {protected RsaCipher cipher;public RsaDecrypter(PrivateKey key) {this.cipher = new RsaCipher(Cipher.DECRYPT_MODE, key);}public String decrypt(byte[] message) {try {return new String(cipher.update(message).doFinal(), "UTF-8");} catch (Exception e) {throw new RuntimeException(e);}}}

摘要

加密并不容易。 简单的示例将为您的应用程序带来带有安全漏洞的实现。 如果需要公用/专用密钥,非对称加密算法,请使用具有4096位密钥的RSA / ECB / OAEPWithSHA–512AndMGF1Padding。

参考资料

Sheth,M.(2017年4月18日)。 Java密码学中的加密和解密。 从https://www.veracode.com/blog/research/encryption-and-decryption-java-cryptography检索。

  • 最佳算法,模式和填充
  • 使用4096位密钥

华盛顿州布莱特韦尔,雨披。 (2015年5月4日)。 ECB模式与RSA加密一起使用是否安全? 从https://crypto.stackexchange.com/questions/25420/is-ecb-mode-safe-to-use-with-rsa-encryption检索。

  • 欧洲央行不适用; Java不会在幕后使用它。
  • RSA使用随机性和填充来避免ECB问题,即相同的明文生成相同的密文

玛丽莲娜。 (2016年11月29日)。 Java –非对称密码术示例。 从https://www.mkyong.com/java/java-asymmetric-cryptography-example/检索。

  • 将公用/专用密钥写入文件
  • 从文件读取公钥/私钥
  • 加密与解密

密钥大小。 (2017年10月12日)。 维基百科。 取自https://en.wikipedia.org/wiki/Key_size 。

  • 到2030年,2048位密钥就足够了
  • 如果需要2030年以后的安全性,则应使用3072位的RSA密钥长度

用户4982。 (2013年11月4日)。 IV如何与RSA加密关联使用? 取自https://crypto.stackexchange.com/questions/11403/how-are-ivs-used-in-association-with-rsa-encryption 。

  • IV值不适用于RSA

翻译自: https://www.javacodegeeks.com/2017/12/choosing-java-cryptographic-algorithms-part-3-public-private-key-asymmetric-encryption.html

非对称加密 公钥私钥

非对称加密 公钥私钥_选择Java加密算法第3部分–公钥/私钥非对称加密相关推荐

  1. 对称密钥加密算法 对称轮数_选择Java加密算法第2部分–单密钥对称加密

    对称密钥加密算法 对称轮数 抽象 这是涵盖Java加密算法的三部分博客系列的第2部分. 该系列涵盖如何实现以下功能: 使用SHA–512散列 AES–256 RSA–4096 这第二篇文章详细介绍了如 ...

  2. 选择Java加密算法第3部分–公钥/私钥非对称加密

    抽象 这是涵盖Java加密算法的三部分博客系列的第3部分. 本系列介绍如何实现以下目标: 使用SHA–512散列 使用AES–256的单密钥对称加密 RSA–4096 这第三篇文章详细介绍了如何实现非 ...

  3. 选择Java加密算法第2部分–单密钥对称加密

    抽象 这是涵盖Java加密算法的三部分博客系列的第2部分. 本系列介绍如何实现以下目标: 使用SHA–512散列 AES–256 RSA–4096 这第二篇文章详细介绍了如何实现单密钥对称AES-25 ...

  4. java加密文件夹_使用java.util.zip压缩文件夹,支持加密,增加描述

    导读热词 下面是编程之家 jb51.cc 通过网络收集整理的代码片段. 编程之家小编现在分享给大家,也给大家做个参考. import java.io.File; import java.io.File ...

  5. java 哈希算法_选择Java密码算法第1部分-哈希

    java 哈希算法 抽象 这是涵盖Java加密算法的三部分博客系列文章的第1部分. 该系列涵盖如何实现以下功能: 使用SHA–512散列 使用AES–256的单密钥对称加密 使用RSA–4096的公钥 ...

  6. java生成公钥和私钥_使用Java生成证书,公钥和私钥

    小编典典 您可以使用一对或密钥在Java中动态生成证书.(公钥,私钥).以BigInteger格式获取这些密钥,并检查以下代码以生成证书. RSAPrivateKeySpec serPrivateSp ...

  7. java 向量存储_关于java:使用AES-256和初始化向量进行加密

    我有一个关于在AES加密中使用初始化向量的问题.我正在引用以下文章/文章以将加密构建到我的程序中: [1]Java 256位AES密码加密[2]http://gmailassistant.source ...

  8. java md5加密64位_基于Java语言的MD5加密Base64转换方法

    1 importjava.io.IOException;2 importjava.math.BigInteger;3 importjava.security.MessageDigest;4 impor ...

  9. python混淆加密ios代码_用AES(MODE_CBC/NoPadding)解密用Python加密的iOS文件

    我从Python中的服务器接收到一个以这种方式加密的文件:import os from Crypto.Cipher import AES from Crypto import Random def p ...

最新文章

  1. linux下有关phy的命令,linux – 如何为Debian安装b43-lpphy-installer?
  2. mfc 找到字符串中字符_利用滑动窗口解LeetCode438题:找到字符串中所有字母异位词...
  3. 华为2017年财报,为何6036亿销售收入,净利润才479亿?
  4. .NET Framework 4.5 五个很棒的特性
  5. 关于ByteBuffer使用解释
  6. VC++中Format用法
  7. trim的返回值php,php trim()函数
  8. 使用系统调用pipe建立一条管道线_使用Unixbench对服务器综合性能打分及测试结果...
  9. Apache Maven 3.0.3 (yum) 安裝 (CentOS 6.4 x64)
  10. 一个介绍傅立叶变换的好文章
  11. 搜狗Q1每天进账1886万,输入法日处理6亿请求成中国最大语音App
  12. MyEclipse的破解
  13. cf手游服务器连接中断,CF手游服务器连接失败怎么回事 无法连接服务器
  14. cad计算机清空按键,cad delete键不能用怎么办-解决cad按delete键不能删除的方法 - 河东软件园...
  15. Python练习题16:人名独特性统计
  16. coreldraw怎么画猴子_小猴子的画法
  17. sql server 2008 r2 忘记sa密码, 没有window账户登录, 解决办法
  18. MYSQL长时间保持连接
  19. C# 重写(override)
  20. RAID5系统架构和扩容

热门文章

  1. P7988-[USACO21DEC] HILO G【set,线段树】
  2. YbtOJ#463-序列划分【二分答案,线段树,dp】
  3. YbtOJ#20064-[NOIP2020模拟赛B组Day4]预算缩减【树形dp】
  4. jzoj5353-村通网【最小生成树】
  5. 初一模拟赛总结(3.30)
  6. P2604 ZJOI2010 网络扩容,费用流裸题
  7. SpringCloud Zuul(三)之常见用法
  8. Dubbo(四)之xml配置方式
  9. 常用公有云接入——华为
  10. java中部的分页实现(二)