RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。

  RSA解决了对称加密的一个不足,比如AES算法加密和解密时使用的是同一个秘钥,因此这个秘钥不能公开,因此对于需要公开秘钥的场合,我们需要在加密和解密过程中使用不同的秘钥,加密使用的公钥可以公开,解密使用的私钥要保密,这就是非对称加密的好处。 

  常用的开发语言来实现RSA加密:

  RSA非对称加密算法实现:Java

  RSA非对称加密算法实现:C#

  RSA非对称加密算法实现:Golang

  RSA非对称加密算法实现:Python

 

  公钥与私钥

  公钥与私钥是成对的,一般的,我们认为的是公钥加密、私钥解密、私钥签名、公钥验证,有人说成私钥加密,公钥解密时不对的。

  公钥与私钥的生成有多种方式,可以通过程序生成(下文具体实现),可以通过openssl工具:  

    # 生成一个私钥,推荐使用1024位的秘钥,秘钥以pem格式保存到-out参数指定的文件中,采用PKCS1格式
openssl genrsa -out rsa.pem 1024
# 生成与私钥对应的公钥,生成的是Subject Public Key,一般配合PKCS8格式私钥使用
openssl rsa -in rsa.pem -pubout -out rsa.pub

  RSA生成公钥与私钥一般有两种格式:PKCS1和PKCS8,上面的命令生成的秘钥是PKCS1格式的,而公钥是Subject Public Key,一般配合PKCS8格式私钥使用,所以就可能会涉及到PKCS1和PKCS8之间的转换:

    # PKCS1格式私钥转换为PKCS8格式私钥,私钥直接输出到-out参数指定的文件中
openssl pkcs8 -topk8 -inform PEM -in rsa.pem -outform pem -nocrypt -out rsa_pkcs8.pem
# PKCS8格式私钥转换为PKCS1格式私钥,私钥直接输出到-out参数指定的文件中
openssl rsa -in rsa_pkcs8.pem -out rsa_pkcs1.pem # PKCS1格式公钥转换为PKCS8格式公钥,转换后的内容直接输出
openssl rsa -pubin -in rsa.pub -RSAPublicKey_out
# PKCS8格式公钥转换为PKCS1格式公钥,转换后的内容直接输出
openssl rsa -RSAPublicKey_in -pubout -in rsa.pub

  现实中,我们往往从pem、crt、pfx文件获取公私和私钥,crt、pfx的制作可以参考:简单的制作ssl证书,并在nginx和IIS中使用,或者使用现成的:https://pan.baidu.com/s/1MJ5YmuZiLBnf-DfNR_6D7A (提取码:c6tj),密码都是:123456

  Java实现

  为简化说明介绍,这里我直接封装了一个工具类,因为要从pem、crt、pfx文件获取公私和私钥,因此引用了一个第三方包:BouncyCastle,可以直接在pom.xml中添加依赖:  

    <dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.68</version>
</dependency>

  或者去mvn上下载:跳转

  简单封装的RsaUtil.java:    

  

import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Enumeration; import javax.crypto.Cipher; import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.DLSequence;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import org.bouncycastle.util.io.pem.PemWriter; public class RsaUtil { static {
Security.addProvider(new BouncyCastleProvider());
} /**
* 随机生成密钥对
*
* @param usePKCS8
* 是否采用PKCS8填充模式
*/
public static Object[] generateRsaKey(boolean usePKCS8) throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME);
// 初始化
keyPairGen.initialize(1024, new SecureRandom());
// 生成一个密钥对,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到私钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 得到公钥 // 这两个公私钥是PKCS8格式的
byte[] publicKeyBytes = publicKey.getEncoded();
byte[] privateKeyBytes = privateKey.getEncoded(); if (!usePKCS8) {
// 将PSCK8格式公私钥转换为PKCS1格式
publicKeyBytes = pkcs8ToPkcs1(false, publicKeyBytes);
privateKeyBytes = pkcs8ToPkcs1(true, privateKeyBytes);
} return new Object[] { publicKeyBytes, privateKeyBytes };
} /**
* 从Pem文件读取密钥对
*
* @param reader
* 输入流
* @param pemFileName
* pem文件
*/
public static byte[] readFromPem(String pemFileName) throws Exception {
PemReader pemReader = new PemReader(new FileReader(pemFileName));
PemObject pemObject = pemReader.readPemObject();
byte[] publicKey = pemObject.getContent();
pemReader.close();
return publicKey;
} /**
* 从Pem文件读取密钥
*
* @param isPrivateKey
* 是否是私钥
* @param buffer
* 字节
* @param pemFileName
* pem文件
*/
public static void writeToPem(byte[] buffer, boolean isPrivateKey, String pemFileName) throws Exception { PemObject pemObject = new PemObject(isPrivateKey ? "RSA PRIVATE KEY" : "RSA PUBLIC KEY", buffer);
FileWriter fileWriter = new FileWriter(pemFileName);
PemWriter pemWriter = new PemWriter(fileWriter);
pemWriter.writeObject(pemObject);
pemWriter.close();
} /**
* 从crt文件读取公钥(pkcs8)
*
* @param crtFileName
* crt文件
* @return 公钥
*/
public static byte[] readPublicKeyFromCrt(String crtFileName) throws Exception {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) cf.generateCertificate(new FileInputStream(crtFileName)); PublicKey publicKey = cert.getPublicKey();
return publicKey.getEncoded();
} /**
* 从pfx文件读取秘钥对(pkcs8)
*
* @param pfxFileName
* pfx文件
* @return 秘钥对
*/
public static Object[] readFromPfx(String pfxFileName, String password) throws Exception {
KeyStore keystore = KeyStore.getInstance("PKCS12");
char[] passwordChars = null;
if (password == null || password.equals("")) {
passwordChars = null;
} else {
passwordChars = password.toCharArray();
}
keystore.load(new FileInputStream(pfxFileName), passwordChars);
Enumeration<String> enums = keystore.aliases(); PrivateKey privateKey = null;
Certificate certificate = null;
while (enums.hasMoreElements()) {
String alias = enums.nextElement();
System.out.println(alias);
if (keystore.isKeyEntry(alias)) {
privateKey = (PrivateKey) keystore.getKey(alias, passwordChars);
certificate = keystore.getCertificate(alias);
}
if (privateKey != null && certificate != null)
break;
}
if (privateKey == null || certificate == null) {
throw new Exception("fail to read key from pfx");
} PublicKey publicKey = certificate.getPublicKey();
return new Object[] { publicKey.getEncoded(), privateKey.getEncoded() };
} /**
* Pkcs8转Pkcs1
*
* @param isPrivateKey
* 是否是私钥转换
* @param buffer
* Pkcs1秘钥
* @return Pkcs8秘钥
* @throws Exception
* 加密过程中的异常信息
*/
public static byte[] pkcs8ToPkcs1(boolean isPrivateKey, byte[] buffer) throws Exception {
if (isPrivateKey) {
PrivateKeyInfo privateKeyInfo = PrivateKeyInfo.getInstance(buffer);
return privateKeyInfo.parsePrivateKey().toASN1Primitive().getEncoded();
} else {
SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(buffer);
return subjectPublicKeyInfo.parsePublicKey().toASN1Primitive().getEncoded();
}
} /**
* Pkcs1转Pkcs8
*
* @param isPrivateKey
* 是否是私钥转换
* @param buffer
* Pkcs1秘钥
* @return Pkcs8秘钥
* @throws Exception
* 加密过程中的异常信息
*/
public static byte[] pkcs1ToPkcs8(boolean isPrivateKey, byte[] buffer) throws Exception {
AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption);
ASN1Primitive asn1Primitive = ASN1Primitive.fromByteArray(buffer);
if (isPrivateKey) {
PrivateKeyInfo privateKeyInfo = new PrivateKeyInfo(algorithmIdentifier, asn1Primitive);
return privateKeyInfo.getEncoded();
} else {
SubjectPublicKeyInfo subjectPublicKeyInfo = new SubjectPublicKeyInfo(algorithmIdentifier, asn1Primitive);
return subjectPublicKeyInfo.getEncoded();
}
} /**
* RSA公钥
*
* @param usePKCS8
* 是否采用PKCS8填充模式
* @param publicKey
* 公钥
* @return 公钥
* @throws Exception
* 加密过程中的异常信息
*/
public static RSAPublicKey generatePublicKey(boolean usePKCS8, byte[] publicKey) throws Exception {
KeySpec keySpec;
if (usePKCS8) {
// PKCS8填充
keySpec = new X509EncodedKeySpec(publicKey);
} else {
// PKCS1填充
DLSequence sequence = (DLSequence) ASN1Primitive.fromByteArray(publicKey);
BigInteger v1 = ((ASN1Integer) sequence.getObjectAt(0)).getValue();
BigInteger v2 = ((ASN1Integer) sequence.getObjectAt(1)).getValue();
keySpec = new RSAPublicKeySpec(v1, v2);
} RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME).generatePublic(keySpec);
return pubKey;
} /**
* RSA私钥
*
* @param usePKCS8
* 是否采用PKCS8填充模式
* @param privateKey
* 私钥
* @return 私钥
* @throws Exception
* 解密过程中的异常信息
*/
public static RSAPrivateKey generatePrivateKey(boolean usePKCS8, byte[] privateKey) throws Exception {
KeySpec keySpec;
if (usePKCS8) {
// PKCS8填充
keySpec = new PKCS8EncodedKeySpec(privateKey);
} else {
// PKCS1填充
DLSequence sequence = (DLSequence) ASN1Primitive.fromByteArray(privateKey);
// BigInteger v1= ((ASN1Integer)sequence.getObjectAt(0)).getValue();
BigInteger v2 = ((ASN1Integer) sequence.getObjectAt(1)).getValue();
BigInteger v3 = ((ASN1Integer) sequence.getObjectAt(2)).getValue();
BigInteger v4 = ((ASN1Integer) sequence.getObjectAt(3)).getValue();
BigInteger v5 = ((ASN1Integer) sequence.getObjectAt(4)).getValue();
BigInteger v6 = ((ASN1Integer) sequence.getObjectAt(5)).getValue();
BigInteger v7 = ((ASN1Integer) sequence.getObjectAt(6)).getValue();
BigInteger v8 = ((ASN1Integer) sequence.getObjectAt(7)).getValue();
BigInteger v9 = ((ASN1Integer) sequence.getObjectAt(8)).getValue();
keySpec = new RSAPrivateCrtKeySpec(v2, v3, v4, v5, v6, v7, v8, v9);
} RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME).generatePrivate(keySpec);
return priKey;
} /**
* RSA公钥加密
*
* @param value
* 加密字符串
* @param publicKey
* 公钥
* @return 密文
* @throws Exception
* 加密过程中的异常信息
*/
public static String rsaEncrypt(String value, RSAPublicKey publicKey) throws Exception {
if (value == null || value.length() == 0)
return ""; // RSA加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] buffer = cipher.doFinal(value.getBytes("utf-8")); // 使用hex格式输出公钥
StringBuffer result = new StringBuffer();
for (int i = 0; i < buffer.length; i++) {
result.append(String.format("%02x", buffer[i]));
}
return result.toString();
} /**
* RSA私钥解密
*
* @param value
* 加密字符串
* @param privateKey
* 私钥
* @return 明文
* @throws Exception
* 解密过程中的异常信息
*/
public static String rsaDecrypt(String value, RSAPrivateKey privateKey) throws Exception {
if (value == null || value.length() == 0)
return ""; byte[] buffer = new byte[value.length() / 2];
for (int i = 0; i < buffer.length; i++) {
buffer[i] = (byte) Integer.parseInt(value.substring(i * 2, i * 2 + 2), 16);
} // RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
buffer = cipher.doFinal(buffer);
return new String(buffer, "utf-8");
} /**
* RSA签名
*
* @param value
* 加密字符串
* @param privateKey
* 私钥
* @param halg
* 加密算法,如MD5, SHA1, SHA256, SHA384, SHA512等
* @return 签名
* @throws Exception
* 签名过程中的异常信息
*/
public static String sign(String value, RSAPrivateKey privateKey, String halg) throws Exception { Signature s = Signature.getInstance(halg.toUpperCase().endsWith("WithRSA") ? halg : (halg + "WithRSA")); s.initSign(privateKey);
s.update(value.getBytes("utf-8")); byte[] buffer = s.sign(); // 使用hex格式输出公钥
StringBuffer result = new StringBuffer();
for (int i = 0; i < buffer.length; i++) {
result.append(String.format("%02x", buffer[i]));
}
return result.toString();
} /**
* RSA签名验证
*
* @param value
* 加密字符串
* @param publicKey
* 公钥
* @param halg
* 加密算法,如MD5, SHA1, SHA256, SHA384, SHA512等
* @return 签名合法则返回true,否则返回false
* @throws Exception
* 验证过程中的异常信息
*/
public static boolean verify(String value, RSAPublicKey publicKey, String signature, String halg) throws Exception {
Signature s = Signature.getInstance(halg.toUpperCase().endsWith("WithRSA") ? halg : (halg + "WithRSA"));
s.initVerify(publicKey);
s.update(value.getBytes("utf-8")); byte[] buffer = new byte[signature.length() / 2];
for (int i = 0; i < buffer.length; i++) {
buffer[i] = (byte) Integer.parseInt(signature.substring(i * 2, i * 2 + 2), 16);
} return s.verify(buffer);
} }

RsaUtil

  生成公钥和私钥:  

    // 生成公私钥
Object[] rsaKey = RsaUtil.generateRsaKey(usePKCS8); //usePKCS8=true表示是否成PKCS8格式的公私秘钥,否则乘车PKCS1格式的公私秘钥
byte[] publicKey = (byte[]) rsaKey[0];
byte[] privateKey = (byte[]) rsaKey[1];

  生成秘钥后,需要保存,一般保存到pem文件中:  

    // 保存到pem文件,filePath是保存目录
RsaUtil.writeToPem(publicKey, false, filePath + "rsa.pub");
RsaUtil.writeToPem(privateKey, true, filePath + "rsa.pem");

  可以保存到pem文件中,当然也可以从pem文件中读取了:  

    // 从Pem文件读取公私钥,filePath是文件目录
byte[] publicKey = RsaUtil.readFromPem(filePath + "rsa.pub");
byte[] privateKey = RsaUtil.readFromPem(filePath + "rsa.pem");

  还可以从crt证书中读取公钥,而crt文件不包含私钥,因此需要单独获取私钥:  

    // 从crt文件读取公钥(crt文件中不包含私钥),filePath是文件目录
byte[] publicKey = RsaUtil.readPublicKeyFromCrt(filePath + "demo.crt");
byte[] privateKey = RsaUtil.readFromPem(filePath + "demo.key");

  pfx文件中包含了公钥和私钥,可以很方便就读取到:  

    // 从pfx文件读取公私钥,filePath是文件目录
Object[] rsaKey = RsaUtil.readFromPfx(filePath + "demo.pfx", "123456");
byte[] publicKey = (byte[]) rsaKey[0];
byte[] privateKey = (byte[]) rsaKey[1];

  有时候我们还可能需要进行秘钥的转换:  

    // Pkcs8格式公钥转换为Pkcs1格式公钥
publicKey = RsaUtil.pkcs8ToPkcs1(false, publicKey);
// Pkcs8格式私钥转换为Pkcs1格式私钥
privateKey = RsaUtil.pkcs8ToPkcs1(true, privateKey);
// Pkcs1格式公钥转换为Pkcs8格式公钥
publicKey = RsaUtil.pkcs1ToPkcs8(false, publicKey);
// Pkcs1格式私钥转换为Pkcs8格式私钥
privateKey = RsaUtil.pkcs1ToPkcs8(true, privateKey);

  有了公钥和私钥,接下就就能实现加密、解密、签名、验证签名等操作了:  

    RSAPublicKey rsaPublicKey = RsaUtil.generatePublicKey(usePKCS8, publicKey);
RSAPrivateKey rsaPrivateKey = RsaUtil.generatePrivateKey(usePKCS8, privateKey); String encryptText = RsaUtil.rsaEncrypt(text, rsaPublicKey);
System.out.printf("【%s】经过【RSA】加密后:%s\n", text, encryptText); String decryptText = RsaUtil.rsaDecrypt(encryptText, rsaPrivateKey);
System.out.printf("【%s】经过【RSA】解密后:%s\n", encryptText, decryptText); String signature = RsaUtil.sign(text, rsaPrivateKey, "MD5");
System.out.printf("【%s】经过【RSA】签名后:%s\n", text, signature); boolean result = RsaUtil.verify(text, rsaPublicKey, signature, "MD5");
System.out.printf("【%s】的签名【%s】经过【RSA】验证后结果是:" + result, text, signature);

  这里完整的demo代码:  

    import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey; public class RsaMain { public static void main(String[] args) {
try {
String text = "上山打老虎";
boolean usePKCS8 = true; // usePKCS8=true表示是否成PKCS8格式的公私秘钥,否则乘车PKCS1格式的公私秘钥
String filePath = RsaUtil.class.getClassLoader().getResource("").getPath();
System.out.printf("文件路径:%s\n", filePath);// 存放pem,crt,pfx等文件的目录
byte[] publicKey, privateKey;// 公钥和私钥 // 生成公私钥
Object[] rsaKey = RsaUtil.generateRsaKey(usePKCS8); // usePKCS8=true表示是否成PKCS8格式的公私秘钥,否则乘车PKCS1格式的公私秘钥
publicKey = (byte[]) rsaKey[0];
privateKey = (byte[]) rsaKey[1];
// 从Pem文件读取公私钥,filePath是文件目录
// publicKey = RsaUtil.readFromPem(filePath + "rsa.pub");
// privateKey = RsaUtil.readFromPem(filePath + "rsa.pem");
// 从pfx文件读取公私钥,filePath是文件目录
// Object[] rsaKey = RsaUtil.readFromPfx(filePath + "demo.pfx",
// "123456");
// publicKey = (byte[]) rsaKey[0];
// privateKey = (byte[]) rsaKey[1];
// 从crt文件读取公钥(crt文件中不包含私钥),filePath是文件目录
// publicKey = RsaUtil.readPublicKeyFromCrt(filePath + "demo.crt");
// privateKey = RsaUtil.readFromPem(filePath + "demo.key"); // 保存到pem文件,filePath是保存目录
RsaUtil.writeToPem(publicKey, false, filePath + "rsa.pub");
RsaUtil.writeToPem(privateKey, true, filePath + "rsa.pem"); // Pkcs8格式公钥转换为Pkcs1格式公钥
publicKey = RsaUtil.pkcs8ToPkcs1(false, publicKey);
// Pkcs8格式私钥转换为Pkcs1格式私钥
privateKey = RsaUtil.pkcs8ToPkcs1(true, privateKey);
// Pkcs1格式公钥转换为Pkcs8格式公钥
publicKey = RsaUtil.pkcs1ToPkcs8(false, publicKey);
// Pkcs1格式私钥转换为Pkcs8格式私钥
privateKey = RsaUtil.pkcs1ToPkcs8(true, privateKey); RSAPublicKey rsaPublicKey = RsaUtil.generatePublicKey(usePKCS8, publicKey);
RSAPrivateKey rsaPrivateKey = RsaUtil.generatePrivateKey(usePKCS8, privateKey); String encryptText = RsaUtil.rsaEncrypt(text, rsaPublicKey);
System.out.printf("【%s】经过【RSA】加密后:%s\n", text, encryptText); String decryptText = RsaUtil.rsaDecrypt(encryptText, rsaPrivateKey);
System.out.printf("【%s】经过【RSA】解密后:%s\n", encryptText, decryptText); String signature = RsaUtil.sign(text, rsaPrivateKey, "MD5");
System.out.printf("【%s】经过【RSA】签名后:%s\n", text, signature); boolean result = RsaUtil.verify(text, rsaPublicKey, signature, "MD5");
System.out.printf("【%s】的签名【%s】经过【RSA】验证后结果是:" + result, text, signature); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

RSA非对称加密算法实现:Java的更多相关文章

  1. RSA 非对称加密算法的Java实现

    关于RSA的介绍Google一下很多,这里不做说明.项目开发中一般会把公钥放在本地进行加密,服务端通过私钥进行解密.Android项目开发中要用到这个加密算法,总结后实现如下: import andr ...

  2. SSH加密原理、RSA非对称加密算法学习与理解

    首先声明一下,这里所说的SSH,并不是Java传统的三大框架,而是一种建立在应用层和传输层基础上的安全外壳协议,熟悉Linux的朋友经常使 用到一 个SSH Secure Shell Cilent的工 ...

  3. RSA非对称加密算法实现:Python

    RSA是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.当时他们三人都在麻省理工学院工作.RSA ...

  4. RSA非对称加密算法实现:Golang

    RSA是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.当时他们三人都在麻省理工学院工作.RSA ...

  5. RSA非对称加密算法实现:C#

    RSA是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.当时他们三人都在麻省理工学院工作.RSA ...

  6. RSA—非对称加密算法

    RSA:非对称加密算法加解密原理如下:已知:p,q,n,e,d,m,c其中:p与q互为大质数,n=p*q 公钥Pk(n,e):加密使用,是公开的 私钥Sk(n,d):解密使用,不公开 c:明文 m:密 ...

  7. RSA非对称加密算法实现过程

    RSA非对称加密算法实现过程 非对称加密算法有很多,RSA算法就是其中比较出名的算法之一,下面是具体实现过程 <?php /** */ class Rsa { /** * private key ...

  8. .NET Core加解密实战系列之——RSA非对称加密算法

    目录 简介 功能依赖 生成RSA秘钥 PKCS1格式 PKCS8格式 私钥操作 PKCS1与PKCS8格式互转 PKCS1与PKCS8私钥中提取公钥 PEM操作 PEM格式密钥读取 PEM格式密钥写入 ...

  9. RSA非对称加密(java实例代码)

    使用RSA对WebService传递的信息加密解密的基本思想是:服务器端提供一个WebService方法String getServerPublicKey(),客户端可以以此得到服务器端的公钥,然后使 ...

随机推荐

  1. Output of C++ Program | Set 16

    Predict the output of following C++ programs. Question 1 1 #include<iostream> 2 using namespac ...

  2. gen already exists but is not a source folder. Convert to a source folder or rename it 的解决办法

    1. Right click on the project and go to "Properties" //鼠标右键点击项目,然后选中Properties   2. Select ...

  3. idea2019.2安裝MybatisCodeHelper插件

    1. 下载MybatisCodeHelper插件 下载已破解的插件压缩包,一定注意校验sha1sum!!! 在IDEA中本地安装插件 激活方法(自2.7.3):IDEA顶部菜单:Tools -> ...

  4. Output of C++ Program | Set 12

    Predict the output of following C++ programs. Question 1 1 #include <iostream> 2 using namespa ...

  5. velocity示例

    创建maven项目 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns ...

  6. dom4j解析XML学习

    原理:把dom与SAX进行了封装 优点:JDOM的一个智能分支.扩充了其灵活性增加了一些额外的功能. package com.dom4j.xml; import java.io.FileNotFoun ...

  7. redis入门到精通系列(六):redis的事务详解

    (一)事务的概念 谈到数据库的高级应用,不可避免会谈到事务.熟悉mysql的朋友们对事务肯定不陌生,简单来讲事务就是控制一个数据库操作序列要么全部执行要么全部不执行.今天我们就来了解redis中的事务 ...

  8. java多线程2:Thread中的方法

    静态方法: Thread类中的静态方法表示操作的线程是"正在执行静态方法所在的代码块的线程". 为什么Thread类中要有静态方法,这样就能对CPU当前正在运行的线程进行操作.下面 ...

  9. IO中同步异步,阻塞与非阻塞 -- 通俗篇

    一.同步与异步 同步/异步, 它们是消息的通知机制 1. 概念解释 A. 同步 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回. 按照这个定义,其实绝大多数函数都是同步调用(例 ...

  10. CF1177A Digits Sequence (Easy Edition) 题解

    Content 一个序列由从 \(1\) 开始的数字不断在末端拼接,就像这样:\(12345678910111213141516...\).现在,给定一个数字 \(k\),请输出这个序列的第 \(k\ ...