公钥密码算法及其JAVA编程
SpringBoot中_JAVA利用国密算法_实现内容的加密_解密

首先来看一下什么是国密算法:国密即国家密码局认定的国产密码算法,即商用密码。
国密主要有SM1,SM2,SM3,SM4。
密钥长度和分组长度均为128位。
1、SM1 为对称加密。
其加密强度与AES(高级加密标准,Advanced Encryption Standard)相当。
该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。
2、SM2为非对称加密,基于ECC。
该算法已公开。
由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。
ECC 256位(SM2采用的就是ECC 256位的一种)安全强度比RSA 2048位高,但运算速度快于RSA。
3、SM3为消息摘要。
可以用MD5作为对比理解。
该算法已公开。
校验结果为256位。
4、SM4为无线局域网标准的分组数据算法。
对称加密,密钥长度和分组长度均为128位。
由于SM1、SM4加解密的分组大小为128bit,故对消息进行加解密时,若消息长度过长,需要进行分组,要消息长度不足,则要进行填充。
在很多地方还是会用到的,这里说一下这个:SM21.在pom.xml中引入依赖jar包:<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.58</version></dependency>2.然后来写一个工具类,用来生成国密的,公钥和私钥这个密码对.import org.bouncycastle.jce.provider.BouncyCastleProvider;import java.security.*;import java.security.spec.ECGenParameterSpec;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.Base64;/*** @author hulala* @Description 国密公私钥对工具类public class KeyUtils {/*** 生成国密公私钥对** @return* @throws Exception*/public static String[] generateSmKey() throws Exception {KeyPairGenerator keyPairGenerator = null;SecureRandom secureRandom = new SecureRandom();ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1");keyPairGenerator = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());keyPairGenerator.initialize(sm2Spec);keyPairGenerator.initialize(sm2Spec, secureRandom);KeyPair keyPair = keyPairGenerator.generateKeyPair();PrivateKey privateKey = keyPair.getPrivate();PublicKey publicKey = keyPair.getPublic();//String[0] 公钥//String[1] 私钥String[] result = {new String(Base64.getEncoder().encode(publicKey.getEncoded())), new String(Base64.getEncoder().encode(privateKey.getEncoded())) };return result;}/*** 将Base64转码的公钥串,转化为公钥对象** @param publicKey* @return*/public static PublicKey createPublicKey(String publicKey) {PublicKey publickey = null;try {X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey));KeyFactory keyFactory = KeyFactory.getInstance("EC", new BouncyCastleProvider());publickey = keyFactory.generatePublic(publicKeySpec);} catch (Exception e) {e.printStackTrace();}return publickey;}/*** 将Base64转码的私钥串,转化为私钥对象** @param privateKey* @return*/public static PrivateKey createPrivateKey(String privateKey) {PrivateKey publickey = null;try {PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));KeyFactory keyFactory = KeyFactory.getInstance("EC", new BouncyCastleProvider());publickey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);} catch (Exception e) {e.printStackTrace();}return publickey;}}3.根据公钥和私钥工具类,生成的密钥对,对数据,进行加密和解密操作import org.bouncycastle.asn1.gm.GMObjectIdentifiers;import org.bouncycastle.crypto.InvalidCipherTextException;import org.bouncycastle.crypto.engines.SM2Engine;import org.bouncycastle.crypto.params.ECDomainParameters;import org.bouncycastle.crypto.params.ECPrivateKeyParameters;import org.bouncycastle.crypto.params.ECPublicKeyParameters;import org.bouncycastle.crypto.params.ParametersWithRandom;import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;import org.bouncycastle.jce.provider.BouncyCastleProvider;import org.bouncycastle.jce.spec.ECParameterSpec;import java.security.*;/*** @author hulala* @Description SM2实现工具类*/public class Sm2Util {static {Security.addProvider(new BouncyCastleProvider());}/*** 根据publicKey对原始数据data,使用SM2加密** @param data* @param publicKey* @return*/public static byte[] encrypt(byte[] data, PublicKey publicKey) {ECPublicKeyParameters localECPublicKeyParameters = null;if (publicKey instanceof BCECPublicKey) {BCECPublicKey localECPublicKey = (BCECPublicKey) publicKey;ECParameterSpec localECParameterSpec = localECPublicKey.getParameters();ECDomainParameters localECDomainParameters = new ECDomainParameters(localECParameterSpec.getCurve(),localECParameterSpec.getG(), localECParameterSpec.getN());localECPublicKeyParameters = new ECPublicKeyParameters(localECPublicKey.getQ(), localECDomainParameters);}SM2Engine localSM2Engine = new SM2Engine();localSM2Engine.init(true, new ParametersWithRandom(localECPublicKeyParameters, new SecureRandom()));byte[] arrayOfByte2;try {arrayOfByte2 = localSM2Engine.processBlock(data, 0, data.length);return arrayOfByte2;} catch (InvalidCipherTextException e) {e.printStackTrace();return null;}}/*** 根据privateKey对加密数据encodedata,使用SM2解密** @param encodedata* @param privateKey* @return*/public static byte[] decrypt(byte[] encodedata, PrivateKey privateKey) {SM2Engine localSM2Engine = new SM2Engine();BCECPrivateKey sm2PriK = (BCECPrivateKey) privateKey;ECParameterSpec localECParameterSpec = sm2PriK.getParameters();ECDomainParameters localECDomainParameters = new ECDomainParameters(localECParameterSpec.getCurve(),localECParameterSpec.getG(), localECParameterSpec.getN());ECPrivateKeyParameters localECPrivateKeyParameters = new ECPrivateKeyParameters(sm2PriK.getD(),localECDomainParameters);localSM2Engine.init(false, localECPrivateKeyParameters);try {byte[] arrayOfByte3 = localSM2Engine.processBlock(encodedata, 0, encodedata.length);return arrayOfByte3;} catch (InvalidCipherTextException e) {e.printStackTrace();return null;}}/*** 私钥签名** @param data* @param privateKey* @return* @throws Exception*/public static byte[] signByPrivateKey(byte[] data, PrivateKey privateKey) throws Exception { Signature sig = Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), BouncyCastleProvider.PROVIDER_NAME);sig.initSign(privateKey);sig.update(data);byte[] ret = sig.sign();return ret;}/*** 公钥验签** @param data* @param publicKey* @param signature* @return* @throws Exception*/public static boolean verifyByPublicKey(byte[] data, PublicKey publicKey, byte[] signature) throws Exception {Signature sig = Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), BouncyCastleProvider.PROVIDER_NAME);sig.initVerify(publicKey);sig.update(data);boolean ret = sig.verify(signature);return ret;}}4.来测试一下,对数据进行加密解密import org.junit.Test;import java.util.Base64;/*** @author hulala* @Description Sm2Util 的测试类*/public class Sm2UtilTest {private String testStr = "wangjing";java.security.PublicKey publicKey = null;java.security.PrivateKey privateKey = null;@Testpublic void test() throws Exception {//生成公私钥对String[] keys = KeyUtils.generateSmKey();System.out.println("原始字符串:" + testStr);System.out.println("公钥:" + keys[0]);publicKey = KeyUtils.createPublicKey(keys[0]);System.out.println("私钥:" + keys[1]);privateKey = KeyUtils.createPrivateKey(keys[1]);System.out.println("");byte[] encrypt = Sm2Util.encrypt(testStr.getBytes(), publicKey);String encryptBase64Str = Base64.getEncoder().encodeToString(encrypt);System.out.println("加密数据:" + encryptBase64Str);byte[] decode = Base64.getDecoder().decode(encryptBase64Str);byte[] decrypt = Sm2Util.decrypt(decode, privateKey);System.out.println("解密数据:" + new String(decrypt));byte[] sign = Sm2Util.signByPrivateKey(testStr.getBytes(), privateKey);System.out.println("数据签名:" + Base64.getEncoder().encodeToString(sign));boolean b = Sm2Util.verifyByPublicKey(testStr.getBytes(), publicKey, sign);System.out.println("数据验签:" + b);}}5.这样就实现了利用国密,SM2进行加密解密了.。
如何利用java程序实现加密所需的公钥、密钥、数字证书

如何利⽤java程序实现加密所需的公钥、密钥、数字证书本篇的主要⽬的在于实现pdf的数字签名问题,只是作为我学习知识的总结。
1、数字签名算法的概述数字签名:私钥⽤于签名,公钥⽤于验证。
数字签名的作⽤:验证数据的完整性,认证数据来源,抗否认。
数字签名实现的具体原理:1、将报⽂按双⽅约定的HASH算法计算得到⼀个固定位数的报⽂摘要。
在数学上保证,只要改动报⽂中任何⼀位,重新计算出的报⽂摘要值就会与原先的值不相符。
这样就保证了报⽂的不可更改性。
(详见参考资料的"公钥密码技术原理"章节)2、将该报⽂摘要值⽤发送者的私⼈密钥加密,然后连同原报⽂和数字证书(包含公钥)⼀起发送给接收者⽽产⽣的报⽂即称数字签名。
3、接收⽅收到数字签名后,⽤同样的HASH算法对报⽂计算摘要值,然后与⽤发送者的公开密钥进⾏解密解开的报⽂摘要值相⽐较,如相等则说明报⽂确实来⾃所称的发送者。
4、同时通过证书颁发机构CA确认证书的有效性即可确认发送的真实⾝份。
常⽤的数字签名有:RSA、DSA、ECDSA2、RSA算法概述RSA是⽬前为⽌应⽤最为⼴泛的⾮对称加密算法。
⾮对称加密算法简单的说就是分成公钥和私钥。
加密和解密采⽤不同的算法实现,这样的好处是不需要像传统对称加密算法⼀样将相同算法的密钥分发给对⽅,从⽽减少密钥被获取所带来的严重危害,⽬前基本上都是采⽤⾮对称算法,⽽RSA是最为⼴泛的。
理论上1024位以上的RSA是⽆法破解的(或者未公开)。
基本原理:⾮对称算法将密码将密码分为公钥和私钥,公钥发送给⽤户(可以是多个),⽤户⽤公钥加密想要发送的数据,然后发送给服务器,服务器通过私钥解密加密后的数据。
基本步骤:⽣成公钥和私钥步骤:1. 随机选择两个不相等的质数p和q2. 计算p和q的乘积n (n的长度就是密钥长度。
3233写成⼆进制是110010100001,⼀共有12位,所以这个密钥就是12位。
实际应⽤中,RSA密钥⼀般是1024位,重要场合则为2048位。
公钥私钥加密解密代码

公钥私钥加密解密代码import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.security.Key;import java.security.KeyPair;import java.security.KeyPairGenerator;import javax.crypto.Cipher;public class RSASecurityUtil2 {/** 指定加密算法为RSA */private static final String ALGORITHM = "RSA";/** 密钥长度,⽤来初始化 */private static final int KEYSIZE = 1024;/** 指定公钥存放⽂件 */private static String PUBLIC_KEY_FILE = "PublicKey";/** 指定私钥存放⽂件 */private static String PRIVATE_KEY_FILE = "PrivateKey";/*** ⽣成密钥对* @throws Exception*/private static void generateKeyPair() throws Exception {// /** RSA算法要求有⼀个可信任的随机数源 */// SecureRandom secureRandom = new SecureRandom();/** 为RSA算法创建⼀个KeyPairGenerator对象 */KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);/** 利⽤上⾯的随机数据源初始化这个KeyPairGenerator对象 */// keyPairGenerator.initialize(KEYSIZE, secureRandom);keyPairGenerator.initialize(KEYSIZE);/** ⽣成密匙对 */KeyPair keyPair = keyPairGenerator.generateKeyPair();/** 得到公钥 */Key publicKey = keyPair.getPublic();/** 得到私钥 */Key privateKey = keyPair.getPrivate();ObjectOutputStream oos1 = null;ObjectOutputStream oos2 = null;try {/** ⽤对象流将⽣成的密钥写⼊⽂件 */oos1 = new ObjectOutputStream(new FileOutputStream(PUBLIC_KEY_FILE));oos2 = new ObjectOutputStream(new FileOutputStream(PRIVATE_KEY_FILE));oos1.writeObject(publicKey);oos2.writeObject(privateKey);} catch (Exception e) {throw e;}finally{/** 清空缓存,关闭⽂件输出流 */oos1.close();oos2.close();}}/*** 加密⽅法* @param source 源数据* @return* @throws Exception*/public static String encrypt(String source) throws Exception { generateKeyPair();Key publicKey;ObjectInputStream ois = null;try {/** 将⽂件中的公钥对象读出 */ois = new ObjectInputStream(new FileInputStream(PUBLIC_KEY_FILE));publicKey = (Key) ois.readObject();} catch (Exception e) {throw e;}finally{ois.close();}/** 得到Cipher对象来实现对源数据的RSA加密 */Cipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, publicKey);byte[] b = source.getBytes();/** 执⾏加密操作 */byte[] b1 = cipher.doFinal(b);BASE64Encoder encoder = new BASE64Encoder();return encoder.encode(b1);}/*** 解密算法* @param cryptograph 密⽂* @return* @throws Exception*/public static String decrypt(String cryptograph) throws Exception { Key privateKey;ObjectInputStream ois = null;try {/** 将⽂件中的私钥对象读出 */ois = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE));privateKey = (Key) ois.readObject();} catch (Exception e) {throw e;}finally{ois.close();}/** 得到Cipher对象对已⽤公钥加密的数据进⾏RSA解密 */ Cipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, privateKey);BASE64Decoder decoder = new BASE64Decoder();byte[] b1 = decoder.decodeBuffer(cryptograph);/** 执⾏解密操作 */byte[] b = cipher.doFinal(b1);return new String(b);}public static void main(String[] args) throws Exception {String source = "恭喜发财!";// 要加密的字符串System.out.println("准备⽤公钥加密的字符串为:" + source);String cryptograph = encrypt(source);// ⽣成的密⽂System.out.print("⽤公钥加密后的结果为:" + cryptograph); System.out.println();String target = decrypt(cryptograph);// 解密密⽂System.out.println("⽤私钥解密后的字符串为:" + target); System.out.println();}}。
javaRSAUtils加密工具类操作

javaRSAUtils加密⼯具类操作1.RSA加密算法是⼀种⾮对称加密算法。
在公开密钥加密和电⼦商业中RSA被⼴泛使⽤。
RSA公开密钥密码体制。
所谓的公开密钥密码体制就是使⽤不同的加密密钥与解密密钥,是⼀种“由已知加密密钥推导出解密密钥在计算上是不可⾏的”密码体制。
在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,⽽解密密钥(即秘密密钥)SK是需要保密的。
加密算法E和解密算法D也都是公开的。
虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。
2.本⼯具类涉及到BASE64编码,所以先展⽰出BASE64Utils:package mon.util;import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder;import java.security.MessageDigest;/*** BASE64的加解密* @author Neo* @date 2018-4-15 22:21:51**/@SuppressWarnings("restriction")public class Base64Utils {public static final String KEY_SHA = "SHA";public static final String KEY_MD5 = "MD5";/*** BASE64解密** @param key* @return* @throws Exception*/public static byte[] decryptBASE64(String key) throws Exception {return (new BASE64Decoder()).decodeBuffer(key);}/*** BASE64加密** @param key* @return* @throws Exception*/public static String encryptBASE64(byte[] key) throws Exception {return (new BASE64Encoder()).encodeBuffer(key);}/*** MD5加密** @param data* @return* @throws Exception*/public static byte[] encryptMD5(byte[] data) throws Exception {MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);md5.update(data);return md5.digest();}/*** SHA加密** @param data* @return* @throws Exception*/public static byte[] encryptSHA(byte[] data) throws Exception {MessageDigest sha = MessageDigest.getInstance(KEY_SHA);sha.update(data);return sha.digest();}}3.然后我们展⽰RSAUtils:package mon.util;import javax.crypto.Cipher;import java.security.*;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.HashMap;import java.util.Map;/*** RSA安全编码组件** @version 1.0* @desc 公钥和私钥存放在properties⽂件的时候每⾏的末尾加上“\r\n\” <br/>* “\r\n” 起到换⾏的作⽤,最后的“\”在properties在⾥表⽰连接** @author Neo* @date 2018-4-15 22:23:19* @since 1.0*/public class RSAUtils extends Base64Utils {public static final String KEY_ALGORITHM = "RSA";public static final String SIGNATURE_ALGORITHM = "MD5withRSA";private static final String PUBLIC_KEY = "RSAPublicKey";private static final String PRIVATE_KEY = "RSAPrivateKey";/*** ⽤私钥对信息⽣成数字签名** @param data 加密数据* @param privateKey 私钥* @return* @throws Exception*/public static String sign(String data, String privateKey) throws Exception {return sign(data.getBytes(), privateKey);}/*** ⽤私钥对信息⽣成数字签名** @param data 加密数据* @param privateKey 私钥* @return* @throws Exception*/public static String sign(byte[] data, String privateKey) throws Exception {// 解密由base64编码的私钥byte[] keyBytes = decryptBASE64(privateKey);// 构造PKCS8EncodedKeySpec对象PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密算法KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);// 取私钥匙对象PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);// ⽤私钥对信息⽣成数字签名Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);signature.initSign(priKey);signature.update(data);return encryptBASE64(signature.sign());/*** 校验数字签名** @param data 加密数据* @param publicKey 公钥* @param sign 数字签名* @return 校验成功返回true 失败返回false* @throws Exception*/public static boolean verify(String data, String publicKey, String sign) throws Exception { return verify(data.getBytes(), publicKey, sign);}/*** 校验数字签名** @param data 加密数据* @param publicKey 公钥* @param sign 数字签名* @return 校验成功返回true 失败返回false* @throws Exception*/public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { // 解密由base64编码的公钥byte[] keyBytes = decryptBASE64(publicKey);// 构造X509EncodedKeySpec对象X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);// KEY_ALGORITHM 指定的加密算法KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);// 取公钥匙对象PublicKey pubKey = keyFactory.generatePublic(keySpec);Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);signature.initVerify(pubKey);signature.update(data);// 验证签名是否正常return signature.verify(decryptBASE64(sign));}/*** 解密<br>* ⽤私钥解密** @param data* @param key* @return* @throws Exception*/public static String decryptByPrivateKey(String data, String key) throws Exception {return new String(decryptByPrivateKey(Base64Utils.decryptBASE64(data), key));}/*** 解密<br>* ⽤私钥解密** @param data* @param key* @return* @throws Exception*/public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {// 对密钥解密byte[] keyBytes = decryptBASE64(key);// 取得私钥PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);// 对数据解密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, privateKey);return cipher.doFinal(data);}/*** 解密<br>* ⽤私钥解密** @param data* @param key* @return* @throws Exception*/public static String decryptByPublicKey(String data, String key) throws Exception { return new String(decryptByPublicKey(Base64Utils.decryptBASE64(data), key)); }/*** 解密<br>* ⽤私钥解密** @param data* @param key* @return* @throws Exception*/public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception { // 对密钥解密byte[] keyBytes = decryptBASE64(key);// 取得公钥X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key publicKey = keyFactory.generatePublic(x509KeySpec);// 对数据解密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, publicKey);return cipher.doFinal(data);}/*** 加密<br>* ⽤公钥加密** @param data* @param key* @return* @throws Exception*/public static String encryptByPublicKey(String data, String key) throws Exception { return Base64Utils.encryptBASE64(encryptByPublicKey(data.getBytes(), key)); }/*** 加密<br>* ⽤公钥加密** @param data* @param key* @return* @throws Exception*/public static byte[] encryptByPublicKey(byte[] data, String key) throws Exception { // 对公钥解密byte[] keyBytes = decryptBASE64(key);// 取得公钥X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key publicKey = keyFactory.generatePublic(x509KeySpec);// 对数据加密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, publicKey);return cipher.doFinal(data);}/*** 加密<br>* ⽤私钥加密** @param data* @param key* @return* @throws Exception*/public static String encryptByPrivateKey(String data, String key) throws Exception { return Base64Utils.encryptBASE64(encryptByPrivateKey(data.getBytes(), key)); }/*** 加密<br>* ⽤私钥加密** @param data* @param key* @return* @throws Exception*/public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception { // 对密钥解密byte[] keyBytes = decryptBASE64(key);// 取得私钥PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);// 对数据加密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, privateKey);return cipher.doFinal(data);}/*** 取得私钥** @param keyMap* @return* @throws Exception*/public static String getPrivateKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY);return encryptBASE64(key.getEncoded());}/*** 取得公钥** @param keyMap* @return* @throws Exception*/public static String getPublicKey(Map<String, Object> keyMap) throws Exception {Key key = (Key) keyMap.get(PUBLIC_KEY);return encryptBASE64(key.getEncoded());}/*** 初始化密钥** @return* @throws Exception*/public static Map<String, Object> initKey() throws Exception {KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024);KeyPair keyPair = keyPairGen.generateKeyPair();// 公钥RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();// 私钥RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();Map<String, Object> keyMap = new HashMap<String, Object>(2);keyMap.put(PUBLIC_KEY, publicKey);keyMap.put(PRIVATE_KEY, privateKey);return keyMap;}public static void main(String[] args) {try {Map<String, Object> map = RSAUtils.initKey();String publicKey = RSAUtils.getPublicKey(map);String privateKey = RSAUtils.getPrivateKey(map);System.out.println("公钥:" + publicKey);System.out.println("私钥:" + privateKey);String data = "Java是世界上最好的编程语⾔";String encryptData = RSAUtils.encryptByPublicKey(data, publicKey);System.out.println("加密后:" + encryptData);String decryptData = RSAUtils.decryptByPrivateKey(encryptData, privateKey);System.out.println("解密后:" + decryptData);} catch (Exception e) {e.printStackTrace();}}}4.最后展⽰测试结果:补充知识:java使⽤RSA⽣成公钥和私钥,并进⾏加解密废话不多说,上代码:import javax.crypto.Cipher;import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.SecureRandom;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.HashMap;import java.util.Map;/*** Java RSA 加密⼯具类*/public class RSAUtils {/*** 密钥长度于原⽂长度对应以及越长速度越慢*/private final static int KEY_SIZE = 1024;/*** ⽤于封装随机产⽣的公钥与私钥*/private static Map<Integer, String> keyMap = new HashMap<Integer, String>();/*** 随机⽣成密钥对* @throws Exception*/public static void genKeyPair() throws Exception {// KeyPairGenerator类⽤于⽣成公钥和私钥对,基于RSA算法⽣成对象KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");// 初始化密钥对⽣成器keyPairGen.initialize(KEY_SIZE, new SecureRandom());// ⽣成⼀个密钥对,保存在keyPair中KeyPair keyPair = keyPairGen.generateKeyPair();// 得到私钥RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();// 得到公钥RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();String publicKeyString = encryptBASE64(publicKey.getEncoded());// 得到私钥字符串String privateKeyString = encryptBASE64(privateKey.getEncoded());// 将公钥和私钥保存到Map//0表⽰公钥keyMap.put(0, publicKeyString);//1表⽰私钥keyMap.put(1, privateKeyString);}//编码返回字符串public static String encryptBASE64(byte[] key) throws Exception {return (new BASE64Encoder()).encodeBuffer(key);}//解码返回bytepublic static byte[] decryptBASE64(String key) throws Exception {return (new BASE64Decoder()).decodeBuffer(key);}/*** RSA公钥加密** @param str 加密字符串* @param publicKey 公钥* @return 密⽂* @throws Exception 加密过程中的异常信息*/public static String encrypt(String str, String publicKey) throws Exception {//base64编码的公钥byte[] decoded = decryptBASE64(publicKey);RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded)); //RSA加密Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, pubKey);String outStr = encryptBASE64(cipher.doFinal(str.getBytes("UTF-8")));return outStr;}/*** RSA私钥解密** @param str 加密字符串* @param privateKey 私钥* @return 明⽂* @throws Exception 解密过程中的异常信息*/public static String decrypt(String str, String privateKey) throws Exception {//64位解码加密后的字符串byte[] inputByte = decryptBASE64(str);//base64编码的私钥byte[] decoded = decryptBASE64(privateKey);RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));//RSA解密Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, priKey);String outStr = new String(cipher.doFinal(inputByte));return outStr;}public static void main(String[] args) throws Exception {long temp = System.currentTimeMillis();//⽣成公钥和私钥genKeyPair();//加密字符串System.out.println("公钥:" + keyMap.get(0));System.out.println("私钥:" + keyMap.get(1));System.out.println("⽣成密钥消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒");String message = "RSA测试aaa";System.out.println("原⽂:" + message);temp = System.currentTimeMillis();String messageEn = encrypt(message, keyMap.get(0));System.out.println("密⽂:" + messageEn);System.out.println("加密消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒");temp = System.currentTimeMillis();String messageDe = decrypt(messageEn, keyMap.get(1));System.out.println("解密:" + messageDe);System.out.println("解密消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒");}}以上这篇java RSAUtils 加密⼯具类操作就是⼩编分享给⼤家的全部内容了,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。
java 接口加密方法

java 接口加密方法Java接口加密方法在软件开发工程师的日常工作中,数据加密是一个非常重要的任务。
为了保护敏感数据的安全性,开发人员需要使用加密算法来防止未经授权的人员访问和窃取数据。
而在Java编程中,接口加密是一种常用的数据加密方法。
本文将详细介绍Java接口加密的方法和步骤。
一、接口加密的原理接口加密是指将原始数据使用特定的算法转换为密文,并将密文发送给接收方。
接收方在接收到密文后,通过相应的解密算法将密文还原为原始数据。
在Java中,常用的接口加密方法有对称加密和非对称加密两种。
1. 对称加密对称加密是指加密和解密使用相同密钥的加密方法。
发送方和接收方使用相同的密钥进行加密和解密操作。
常见的对称加密算法有DES、AES、RC4等。
对称加密的优点是加密解密速度快,缺点是密钥的分发和管理工作相对复杂。
2. 非对称加密非对称加密是指加密和解密使用不同密钥的加密方法。
发送方使用接收方的公钥进行加密,接收方使用自己的私钥进行解密。
常见的非对称加密算法有RSA、DSA等。
非对称加密的优点是密钥的分发和管理相对简单,但加密解密过程相对较慢。
二、接口加密的步骤接口加密主要包括密钥生成、加密和解密三个步骤。
下面将逐步介绍这三个步骤的具体实现方法。
1. 密钥生成在使用接口加密之前,首先需要生成密钥。
对称加密的密钥可以使用随机数生成器生成,例如:SecretKey key = KeyGenerator.getInstance("AES").generateKey(); 非对称加密的密钥通常使用公钥私钥对生成,例如:KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(1024);KeyPair keyPair = keyGen.generateKeyPair();PublicKey publicKey = keyPair.getPublic();PrivateKey privateKey = keyPair.getPrivate();2. 加密在生成密钥后,可以使用密钥进行加密操作。
java id加密方法

java id加密方法Java是一种广泛应用于软件开发的编程语言,具有简洁、可移植、面向对象等特点。
在Java中,可以使用id加密方法来保护用户的个人信息和数据安全。
本文将介绍一种基于Java的id加密方法,并详细解析其原理和实现步骤。
一、加密算法的选择在实现id加密方法时,首先需要选择一种合适的加密算法。
常见的加密算法有对称加密算法和非对称加密算法。
对称加密算法使用相同的密钥进行加密和解密,速度快但安全性较低;非对称加密算法使用公钥和私钥进行加密和解密,安全性高但速度较慢。
根据实际需求,可以选择适合的加密算法进行id加密。
二、加密步骤的设计在设计id加密方法时,需要考虑以下几个步骤:1. 生成密钥:根据选择的加密算法,生成密钥对或密钥。
2. 加密数据:使用生成的密钥对或密钥,对id进行加密操作。
3. 存储密文:将加密后的id存储到数据库或文件中,确保数据安全。
4. 解密数据:在需要使用id时,使用相同的密钥对或密钥,对密文进行解密操作。
三、实现方法的示例下面以对称加密算法AES为例,演示一个基于Java的id加密方法的实现步骤。
1. 导入相关库:import javax.crypto.Cipher;import javax.crypto.KeyGenerator;import javax.crypto.SecretKey;2. 生成密钥:KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");keyGenerator.init(128);SecretKey secretKey = keyGenerator.generateKey();3. 加密数据:Cipher cipher = Cipher.getInstance("AES");cipher.init(Cipher.ENCRYPT_MODE, secretKey);byte[] encryptedId = cipher.doFinal(id.getBytes());4. 存储密文:将encryptedId存储到数据库或文件中。
Java使用数字证书加密文件(含代码)

JA V A 使用数字证书加密解密文件总结目录1.编写目的 (3)2.JA V A生产数字证书 (4)2.1.1 keystore(JKS) 的生成 (4)2.1.2 导出公钥 (5)3.使用JKS私钥加密文件 (5)4.转换为PFX格式私钥 (6)5.使用PFX加密文件 (7)6 源代码 (8)6.1 用到的JAR包 (8)6.2 示例代码 (8)6.2.1 Test.java (8)6.2.2 RsaUtil.java (10)6.2.3 Base64.java (19)7.结束语 (26)1.编写目的学习RSA算法,读取数字证书中的私钥对文件进行加密,使用数字证书的公钥解密,这种方式就是RSA算法.自己对RSA算法的理解:⏹私钥加密公钥解密:如果用私钥对文件加密,发给别人,别人用我公布的公钥进行解密,实现这个文件就是我本人制作的,不是别人做的.⏹公钥加密私钥解密:如果别人用我的公钥加密文件,那么只能我一个人看,只有使用我的私钥进行解密,私钥一定是不能告诉其他人的.本文讲解如何用JKS私钥对文件进行加密,用对于CRT公钥进行解密,将JKS私钥转换为PFX格式私钥,并用PFX私钥对文件进行加密解密Jks:是JA V A的keytools证书工具支持的证书私钥格式pfx:是微软支持的私钥格式⏹2.JAVA生产数字证书为了实现数字证书加密文件,我们首先要制作几个数字证书,如果你已经有了pfx格式的数字证书并且知道其密码,以及对应crt或者cer格式的公钥证书则跳过本章.2.1 keytool 创建数字证书Keytool是一个Java数据证书的管理工具,Keytool将密钥(key)和证书(certificates)存在一个称为keystore的文件中在keystore里,包含两种数据:⏹密钥实体(Key entity):密钥(secret key)又或者是私钥⏹配对公钥(采用非对称加密):可信任的证书实体(trusted certificate entries),只包含公钥2.1.1 keystore(JKS) 的生成●分阶段生成:命令格式:keytool -genkey -alias yushan(别名) -keypass yushan(别名密码) -keyalg RSA(算法) -keysize 1024(密钥长度) -validity 365(有效期,天单位) -keystore e:\yushan.keystore(指定生成证书的位置和证书名称) -storepass 123456(获取keystore信息的密码);示例:1)cmd下进入java/bin2)输入命令keytool -genkey -alias myalias-keypass 123456-keyalg RSA-keysize 1024 -validity 365 -keystore d: \myalias.keystore -storepass 123456●一次性生成:keytool -genkey -alias yushan -keypass yushan -keyalg RSA -keysize 1024 -validity 365 -keystore e:\yushan.keystore -storepass 123456 -dname "CN=(名字与姓氏), OU=(组织单位名称), O=(组织名称), L=(城市或区域名称), ST=(州或省份名称), C=(单位的两字母国家代码)";(中英文即可)无例图2.1.2 导出公钥命令:keytool -export -alias myalias -keystore d:\myalias.keystore -file d:\myalias.crt -storepass 123456创建结果:3.使用JKS私钥加密文件//工具类RSAUtil rsa = new RSAUtil();//从jks私钥中获取私钥加密串PrivateKey priKeyFromKs = rsa.getPriKeyFromKS("d:\\myalias.keystore","123456", "myalias", "123456");//从jks私钥中获取公钥解密串PublicKey pubKeyFromKS = rsa.getPubKeyFromKS("d:\\myalias.keystore", "123456", "myalias");//从crt公钥中获取公钥解密串PublicKey pubKeyFromCrt = rsa.getPubKeyFromCRT("d:\\myalias.crt");//用私钥串加密rsa.encryptWithPrv("d:\\file.xml",priKeyFromKs,"d:\\file_encWithKSPri.xml", true);//用jks公钥串解密rsa.decryptWithPub("d:\\file_encWithKSPri.xml", pubKeyFromKS, true,"d:\\file_encWithKSPri_decKs.xml");//用crt公钥串解密rsa.decryptWithPub("d:\\file_encWithKSPri.xml", pubKeyFromCrt, true, "d:\\file_encWithKSPri_decCrt.xml");4.转换为PFX格式私钥如果你已经有了pfx格式的数字证书并且知道其密码,以及对应crt或者cer格式的公钥证书则跳过本章.4.1 转换工具转换工具我使用的是kestore-export下载kestore-export.rar 请百度搜索,我也会往CSDN上上传,请直接搜索kestore-export.rar。
c语言rsa公钥密码设计

RSA公钥密码设计是一种非对称加密算法,它使用一对密钥进行加密和解密。
在C语言中,实现RSA公钥密码设计的步骤如下:生成一对公钥和私钥RSA算法需要使用一对公钥和私钥。
公钥用于加密数据,私钥用于解密数据。
生成公钥和私钥的代码如下:c#include <openssl/rsa.h>#include <openssl/pem.h>#include <openssl/err.h>RSA *generate_rsa_key(int bits) {RSA *rsa = RSA_new();BIGNUM *e = BN_new();BN_set_word(e, RSA_F4); // 公共指数为RSA_F4RSA_generate_key_ex(rsa, bits, e, NULL); // 生成密钥对BN_free(e);return rsa;}加密数据使用公钥加密数据的代码如下:c#include <openssl/evp.h>#include <openssl/buffer.h>#include <string.h>int encrypt_data(unsigned char *plaintext, int plaintext_len, RSA *rsa_pub, unsigned char **ciphertext) {int ciphertext_len;EVP_PKEY *pkey = NULL;EVP_PKEY_assign_RSA(pkey, rsa_pub); // 将RSA公钥赋值给EVP_PKEY结构体if (EVP_PKEY_encrypt(pkey, ciphertext, &ciphertext_len, plaintext, plaintext_len) != 1) { // 加密数据return -1; // 加密失败}*ciphertext = (unsigned char *)malloc(ciphertext_len); // 分配足够的内存空间存储密文if (EVP_PKEY_encrypt(pkey, ciphertext, &ciphertext_len, plaintext, plaintext_len) != 1) { // 再次加密数据,确保数据正确加密return -1; // 加密失败}return ciphertext_len; // 返回密文长度}解密数据使用私钥解密数据的代码如下:c#include <openssl/evp.h>#include <openssl/buffer.h>#include <string.h>int decrypt_data(unsigned char *ciphertext, int ciphertext_len, RSA *rsa_pri, unsigned char **plaintext) {int plaintext_len;EVP_PKEY *pkey = NULL;EVP_PKEY_assign_RSA(pkey, rsa_pri); // 将RSA私钥赋值给EVP_PKEY结构体if (EVP_PKEY_decrypt(plaintext, ciphertext, &plaintext_len, pkey, NULL) != 1) { // 解密数据,得到明文数据指针和长度信息,plaintext为指向明文数据的指针,plaintext长度为plaintext 指向的数据的长度,NULL表示不指定填充方案,系统默认的填充方案是PKCS#1方案。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1786 95 mod 2537 787 58 95 1786 mod 2537 34129 2228 mod 2537 2116 14 2228 341 mod 2537 2188 7 1185 mod 2537 25 3 1185 2188 mod 2537 1520 mod 2537 最后得明文 M 1520
解密过程
M 95 937 mod 2537 468 M 1414 95 mod 2537 M 240
234
95 mod 2537
3、对 RSA 算法方法的攻击 (1)强行攻击:对所有的私有密钥都进行尝试。 (2)数学攻击:等效于对两个素数乘积的因数分解。 (3)定时攻击:这依赖于解密算法的运行时间。 强行攻击 强行攻击是对所有的私有密钥都进行尝试(一般需要尝试一半
n p 1q 1 ,然后可以确定 d e 1 mod n 。 (2)在不先确定 p 和 q 的情况下直接确定 n 。同样可以确定 d e 1 mod n 。 (3)不先确定 n 而直接确定 d 。
大部分关于 RSA 密码分析的讨论都集中在对 n 进行素因子分 解上。 给定 n 确定 n 就等价于对 n 进行因子分解。 给定 e 和 n 时 使用目前已知的算法求出 d 似乎在时间开销上至少和因子分解问 题一样大。对于一个具有大的素因子的大数,因子分解是一个难 题,最近对 RSA–130 的攻击使用广义数域筛法。用这种方法能够 仅用 10%的计算量进行分解,而特殊数域筛可以用比广义数域筛 快得多的速度分解一个特殊形式的数。因而我们需要小心地选取 RSA 的密钥大小。 定时攻击 窥探者可以通过监视一台计算机解密报文所花费的时间来确 定私有密钥。定时攻击不仅可以用于 RSA,还可以用于其他公开密 钥密码系统。它的攻击方式与常规的方式完全不同,并且它是一 种只用到密文的攻击方式。定时攻击有点像一个窃贼通过观察一 个人转动拨号盘拨出一个个数自所用的时间来猜测一个保险箱的 数字组合。 虽然定时攻击是一种严重的威胁,但是却有简单的防范措施 可以采用,这包括: (1)常数取幂时间:保证所有取密操作在返 回一个结果之前 花费同样多的时间。这是一个不大的更改,但是 确实使算法性能下降。 (2) 随机延时:可以通过对取幂算法增加
e d e
因为 ed 1 mod n , M
ed
M C d mod n M
M mod n
e d
mod n M ed mod n
2、RSA 算法举例 下面举个具体例子说明加密和解密过程。 加密过程 取明文为 1520 设 p 43 , q 59 , n 43 59 2537
6.2
RSA 算法的原理
RSA (Rivest Shamir Adleman)算法是由美国麻省理工学院的 Ron Rivest,Adi Shamir 和 Len Adleman 于 1977 年研制并于 1978 年发表的一种算法。目前,此方案被广泛接受并成为通用公开密 钥加密算法。 1、RSA 算法的描述: 1、 取两个素数 p 和 q (保密) 2、 计算 n pq (公开) ,
e
的个数,以上算法要做 t 1 次平方和( we -1)次乘法运算。如 果 e 是在区间 0 e m 上随机选取的,则预期需要大约 1 / 2lg n 1 次乘法。 2、从左到右的二进制幂模法 输入:正整数 m ,小于 m 的整数 g 及正整数 e et et 1 e1e0 2 。 输出: g mod m 。 (1) s 1 。 (2)对 i 从 t 依次到 0,执行: ① s ss mod m ; ②如果 ei 1, s sg mod m 。 (3) 返回 s 。
3、 n p 1q 1 (保密)
4、随机选取整数 e ,满足 gcd e, n 1 (公开) 5、计算 d ,满足 ed 1 mod n (保密) 加密算法: C M mod n 解密算法: M C mod n 算法验证: C M mod n
1520 2
同理
1730 mod 2537
C 1730 6 1520 mod 2537 C 1777 1520 mod 2537
3 2
C 1730 2 1520 mod 2537
3
C 1777 1777 1520 mod 2537 C 1701 1777 1520 mod 2537 因为 1777 1520 1672 mod 2537 C 1701 1672 mod 2537 因为 1701 1672 95 mod 2537 C 95 mod 2537 最后得密文 C 0095 。
n
实验指导 2、 安装 JDK1.3。 3、 取要测试的数 m 为 1999 (实验用的默认数, 程序中已经定义) , 取固定值正整数 n 为 20 (实验用的默认数, 程序中已经定义) , 对应素数的概率为 99.9999%。 4、 程序取名 C431.java 编译、运行。
5、 结果显示 true。即数 1999 为素数的概率为 99.9999%。 6、 自行实验: 在源程序中修改定义不同的测试数 m 和 n 重复上述 实验过程。 JAVA 源程序 // 程序名 : C431.java // 目的 : 用于 JAVA 课 RSA 中素数测试演示 // 修改时间: 2004 年 4 月 2 日 import java.math.*; public class C431{ public static void main(String[] arge){ String number="1999"; BigInteger m=new BigInteger(number); int n=20; boolean result=m.isProbablePrime(n); System.out.print(result); } }//display true 6.3.3 素数生成类的设计 素数的生成过程为:随意取一个数,然后测试素数性,如果 测试成功,则找到了所要的数,否则在数字中加 1 然后重试,一 直重复直到生成素数。生成素数的方法有多种,但通常使用试错 法就可以了。选取一个素数的过程为: 1、 随机选一个整数 n 。 2、 完成随机素数性检验,如果 n 没有通过检验, n 1 并转到步 骤 1。 3、 如果 n 通过了检验,就接受 n 。 这是一个有点烦琐的过程。然而,相对来说并不经常进行这 个过程,只有在需要一对新的密钥时才需要进行一次。 6.3.4 素数生成类的实验指导及源程序
160
,也许会大到 2
1024 e
。下面我们讨
论幂模计算的方法, 即对某正整数 g 和 e , 求 g mod m 的算法。 (1输入:正整数 m ,小于 m 的整数 g 及整数 e 1 。 输出: g mod m 。 (1) s 1, r g (2)当 e 0 执行: ①如果 e 是奇数,则 s sr mod m ; ② e e / 2 ; ③如果 e 0 , r rr mod m 。 (3)返回 s 。 如果 t 是 e 的二进制表示的比特长度, we 是该表示中的 1
n p 1q 1 42 58 2436 取 e 13, de 13d 1 mod 2436 得 d 937 e 由加密算法 C M mod n C 152013 mod 2537
C 1520 2
6
1520 mod 2537
e
6.3
RSA 算法的 JAVA 编程
6.3.1 素数测试类的设计 检验素数性方面已经出现了许多方法,几乎所有的方法都是 概率性质的,也就是说,这个检验只是确定一个给定的整数可能 是素数。虽然缺乏完全的确定性,但是这些检验在运行时可以按 照需要做到使得概率尽可能地接近 1。 检验一个给定整数是否是素 数的过程是完全涉及 n 和一个随机选取的整数 a 的素数性检验计 算过程。如果 n 没有通过这次检验,那么 n 就不是一个素数。如 果 n 通过了这次检验,那么 n 可能是素数也可能不是。如果 n 通 过了许多这种检验,其中涉及许多随机选取的 a 值,那么就对于 n 是素数有了很高的信心。 对于较小的数(32 位以下),判断一个数是否是素数的简单方 法是求因子。如果除了 1 和本身之外没有别的因子,则此数是素 数。通常,素数的测试用于较大数。这些测试确定一个数为素数 的 可 能 性 。 一 个 常 见 的 方 法 是 利 用 JAVA 的 BigInteger 类 的 isProbablePrime()方法。这个方法取 n 值作为变元,对于固定值 m,如果 BigInteger 为素数的概率大于 1 2 ,则返回 true。当 n 等于 10 时,素数的概率为 99.9%,当 n 等于 20 时,素数的概 率为 99.9999%。 下面的程序显示如何用 BigInteger 的 isProbahlePrime() 方法测试素数。程序取固定值(正整数)n 和要测试的数 m,然后返 回一个概率结果 result。 6.3.2 素数测试类的实验指导及源程序
第 6 章公钥密码算法及其 JAVA 程序设计
6.1 公钥密码
公开密钥密码编码学的发展是整个密码编码学历史上一个革 命。从最初一直到现代,几乎所有密码编码系统都建立在基本的 替代和置换工具的基础上。 公开密钥密码编码学则与以前的所有 方法都截然不同。一方面公开密钥算法基于数学中的数论而不是 替代和置换,更重要的是,公开密钥密码编码学是非对称的,它 用到两个不同的密钥,而对称的常规加密则只使用一个密钥。使 用两个密钥对于保密通信、密钥分配和鉴别等领域都有着深远的 影响。公开密钥密码编码学是为解决常规加密面临的密钥分配问 题而发展起来的。由于公钥加密在计算上的巨大开销,当前的使 用只限于密钥管理和数字签名等应用。 公开密钥算法用一个密钥进行加密,而用另一个不同但是有 关的密钥进行解密。算法有以下重要特性: (1)仅仅知道密码算 法和加密密钥而要确定解密密钥,在计算上是不可能的。 (2)两 个相关密钥中任何一个都可以用作加密而让另外一个用作解密。 使用步骤如下: (1)网络中的每个端系统都产生一对用于它将接 收的报文进行加密和解密的密钥。 (2)每个系统都通过把自己的 加密密钥放进一个登记本或者文件来公布它,这就是公钥。另一 个密钥则是私有的。 (3)如果 A 想给 B 发送一个报文,他就用 B 的公钥加密这个报文。 (4)B 收到这个报文后就用他的保密密钥解 密报文。其他所有收到这个报文的人都无法解密它,因为只有 B 才有 B 的私有密钥。 使用这种方法,所有参与方都可以获得各个 公开密钥,而各参与方的私有密钥由各参与方自己在本地产生, 因此不需要被分配得到。为了区分常规和公开密钥加密这两个体 制,我们一般将常规加密中使用的密钥称为秘密密钥,公开密钥 加密中使用的两个密钥则称为公开密钥和私有密钥。在任何时候 私有密钥都是保密的,但我们把它称为私有密钥而不是秘密密钥, 以免同常规加密中使用的秘密密钥混淆。