文章目录
Pre
加密与安全_探索非对称加密算法_RSA算法
概述
在数字化时代,网络通信的安全性是必须关注的重要问题之一。非对称加密算法作为现代密码学的重要组成部分,为保护通信的隐私提供了一种可靠的解决方案。
什么是非对称加密算法?
非对称加密算法,又称为公钥加密算法,是一种密码学中的重要概念。它与传统的对称加密算法不同,需要一对密钥:公钥和私钥。这对密钥之间存在着特殊的数学关系,但无法通过公钥推导出私钥,从而保证了通信的安全性。
如何工作?
当发送方A希望将数据发送给接收方B时,A可以使用B的公钥对数据进行加密,得到密文。只有拥有对应私钥的B才能解密这个密文。同样地,B也可以使用A的公钥加密数据,只有A持有私钥才能解密。这种加密和解密使用不同的密钥的特点,使得非对称加密算法成为了保护通信隐私的重要工具。
示例:RSA算法
RSA算法是非对称加密算法中最常见的一种,它利用了大数分解的数学难题,保证了通信的安全性。在RSA算法中,公钥是公开的,私钥是保密的。发送方使用接收方的公钥对数据进行加密,而接收方使用自己的私钥进行解密,从而实现了安全的通信。
特点和优势
- 加密和解密使用不同的密钥,提高了通信的安全性。
- 如果使用私钥加密,只能使用公钥解密;反之亦然。
- 非对称加密算法安全性高,但处理数据速度较慢。
ECC:另一种非对称加密算法
除了RSA算法,还有一种备受关注的非对称加密算法,即椭圆曲线密码学(ECC)。ECC利用了椭圆曲线上的数学难题,相比RSA算法,它能够以更短的密钥长度实现相当于甚至更高的安全级别,同时在资源受限的环境下拥有更好的性能表现。
Code
生成公钥和私钥
packagecom.artisan;importcom.sun.org.apache.xml.internal.security.utils.Base64;importjava.security.KeyPair;importjava.security.KeyPairGenerator;importjava.security.PrivateKey;importjava.security.PublicKey;/**
* @author 小工匠
* @version 1.0
*/publicclassRsaKeyPair{publicstaticvoidmain(String[] args)throwsException{// 指定加密算法为RSAString algorithm ="RSA";// 创建密钥对生成器对象KeyPairGenerator keyPairGenerator =KeyPairGenerator.getInstance(algorithm);// 生成RSA密钥对KeyPair keyPair = keyPairGenerator.generateKeyPair();// 获取生成的私钥PrivateKey privateKey = keyPair.getPrivate();// 获取生成的公钥PublicKey publicKey = keyPair.getPublic();// 获取私钥的编码字节数组byte[] privateKeyEncoded = privateKey.getEncoded();// 获取公钥的编码字节数组byte[] publicKeyEncoded = publicKey.getEncoded();// 对公私钥的编码字节数组进行Base64编码String privateKeyString =Base64.encode(privateKeyEncoded);String publicKeyString =Base64.encode(publicKeyEncoded);// 打印私钥的Base64编码字符串System.out.println(privateKeyString);System.out.println("----------------------------------");// 打印公钥的Base64编码字符串System.out.println(publicKeyString);}}
使用RSA算法生成一个密钥对,并将私钥和公钥进行Base64编码后打印出来了。
私钥加密
packagecom.artisan;importcom.sun.org.apache.xml.internal.security.utils.Base64;importjavax.crypto.Cipher;importjava.security.KeyPair;importjava.security.KeyPairGenerator;importjava.security.PrivateKey;importjava.security.PublicKey;/**
* @author 小工匠
* @version 1.0
* @mark: 显示代码,改变世界
*/publicclassPrivateKeyEnc{publicstaticvoidmain(String[] args)throwsException{String input ="小工匠的IT生活";// 指定加密算法为RSAString algorithm ="RSA";// 创建密钥对生成器对象KeyPairGenerator keyPairGenerator =KeyPairGenerator.getInstance(algorithm);// 生成RSA密钥对KeyPair keyPair = keyPairGenerator.generateKeyPair();// 获取生成的私钥PrivateKey privateKey = keyPair.getPrivate();// 获取生成的公钥PublicKey publicKey = keyPair.getPublic();// 获取私钥的编码字节数组byte[] privateKeyEncoded = privateKey.getEncoded();// 获取公钥的编码字节数组byte[] publicKeyEncoded = publicKey.getEncoded();// 对公私钥的编码字节数组进行Base64编码String privateKeyString =Base64.encode(privateKeyEncoded);String publicKeyString =Base64.encode(publicKeyEncoded);// 打印生成的密钥对System.out.println("私钥(Base64编码): "+ privateKeyString);System.out.println("公钥(Base64编码): "+ publicKeyString);// 创建加密对象,参数表示加密算法Cipher cipher =Cipher.getInstance(algorithm);// 初始化加密对象// 第一个参数:加密模式// 第二个参数:使用私钥进行加密
cipher.init(Cipher.ENCRYPT_MODE, privateKey);// 使用私钥加密输入的字符串byte[] encryptedBytes = cipher.doFinal(input.getBytes());// 对加密后的字节数组进行Base64编码,并打印System.out.println("加密后的字符串(Base64编码): "+Base64.encode(encryptedBytes));}}
私钥加密私钥解密 ( 行不通 )
在上面的代码上追加
// 私钥进行解密 (错误的演示)
cipher.init(Cipher.DECRYPT_MODE,privateKey);// 对密文进行解密,不需要使用base64,因为原文不会乱码byte[] bytes1 = cipher.doFinal(encryptedBytes);System.out.println(newString(bytes1));
私钥加密公钥解密
将上述代码的 私钥解密,换成使用公钥解密
// 公钥进行解密
cipher.init(Cipher.DECRYPT_MODE,publicKey);// 对密文进行解密,不需要使用base64,因为原文不会乱码byte[] bytes1 = cipher.doFinal(encryptedBytes);System.out.println("解密后的字符串: "+newString(bytes1));
公钥加密和公钥解密 (行不通)
保存公钥和私钥
生成RSA非对称加密算法的密钥对,并将生成的公钥和私钥保存在本地文件中。
packagecom.artisan;importcom.sun.org.apache.xerces.internal.impl.dv.util.Base64;importorg.apache.commons.io.FileUtils;importjava.io.File;importjava.nio.charset.Charset;importjava.security.*;publicclassKeyPairOperate{publicstaticvoidmain(String[] args)throwsException{// 加密算法String algorithm ="RSA";// 生成密钥对并保存在本地文件中generateKeyToFile(algorithm,"a.pub","a.pri");}/**
* 生成密钥对并保存在本地文件中
*
* @param algorithm : 算法
* @param pubPath : 公钥保存路径
* @param priPath : 私钥保存路径
* @throws Exception
*/privatestaticvoidgenerateKeyToFile(String algorithm,String pubPath,String priPath)throwsException{// 获取密钥对生成器KeyPairGenerator keyPairGenerator =KeyPairGenerator.getInstance(algorithm);// 获取密钥对KeyPair keyPair = keyPairGenerator.generateKeyPair();// 获取公钥PublicKey publicKey = keyPair.getPublic();// 获取私钥PrivateKey privateKey = keyPair.getPrivate();// 获取byte数组byte[] publicKeyEncoded = publicKey.getEncoded();byte[] privateKeyEncoded = privateKey.getEncoded();// 进行Base64编码String publicKeyString =Base64.encode(publicKeyEncoded);String privateKeyString =Base64.encode(privateKeyEncoded);// 保存文件FileUtils.writeStringToFile(newFile(pubPath), publicKeyString,Charset.forName("UTF-8"));FileUtils.writeStringToFile(newFile(priPath), privateKeyString,Charset.forName("UTF-8"));}}
读取私钥
// 读取私钥PrivateKey privateKey =readPrivateKeyFromFile(algorithm,"a.pri");byte[] encoded = privateKey.getEncoded();String privateContent =Base64.encode(encoded);System.out.println("私钥内容:"+ privateContent);
/**
* @param algorithm
* @param filePath
* @return
* @throws Exception
*/privatestaticPrivateKeyreadPrivateKeyFromFile(String algorithm,String filePath)throwsException{// 从文件中读取私钥字符串String privateKeyString =FileUtils.readFileToString(newFile(filePath),StandardCharsets.UTF_8);// 进行Base64解码byte[] privateKeyEncoded =Base64.decode(privateKeyString);// 获取密钥工厂KeyFactory keyFactory =KeyFactory.getInstance(algorithm);// 构建密钥规范 进行Base64解码PKCS8EncodedKeySpec spec =newPKCS8EncodedKeySpec(Base64.decode(privateKeyString));return keyFactory.generatePrivate(spec);}
看下生成的文件中的内容:
读取公钥
// 读取公钥PublicKey publicKey =readPublicKeyFromFile(algorithm,"a.pub");byte[] publicKeyEncoded = publicKey.getEncoded();String publicContent =Base64.encode(publicKeyEncoded);System.out.println("公钥内容:"+ publicContent);
/**
* @param algorithm
* @param filePath
* @return
* @throws Exception
*/privatestaticPublicKeyreadPublicKeyFromFile(String algorithm,String filePath)throwsException{// 将文件内容转为字符串String publicKeyString =FileUtils.readFileToString(newFile(filePath),StandardCharsets.UTF_8);// 获取密钥工厂KeyFactory keyFactory =KeyFactory.getInstance(algorithm);// 构建密钥规范 进行Base64解码X509EncodedKeySpec spec =newX509EncodedKeySpec(Base64.decode(publicKeyString));// 生成公钥return keyFactory.generatePublic(spec);}
使用读取的公钥加密,私钥解密
// 使用公钥私钥实现加解密String text ="小工匠的IT生活";System.out.println("原文:"+ text);String enc =encryptRSA(algorithm, publicKey, text);System.out.println("公钥加密后的数据:"+ enc);String plainText =decryptRSA(algorithm, privateKey, enc);System.out.println("私钥解密后的数据:"+ plainText);
/**
* 解密数据
*
* @param algorithm : 算法
* @param encrypted : 密文
* @param key : 密钥
* @return : 原文
* @throws Exception
*/publicstaticStringdecryptRSA(String algorithm,Key key,String encrypted)throwsException{// 创建加密对象// 参数表示加密算法Cipher cipher =Cipher.getInstance(algorithm);// 私钥进行解密
cipher.init(Cipher.DECRYPT_MODE, key);// 由于密文进行了Base64编码, 在这里需要进行解码byte[] decode =Base64.decode(encrypted);// 对密文进行解密,不需要使用base64,因为原文不会乱码byte[] bytes1 = cipher.doFinal(decode);returnnewString(bytes1);}/**
* 使用密钥加密数据
*
* @param algorithm : 算法
* @param input : 原文
* @param key : 密钥
* @return : 密文
* @throws Exception
*/publicstaticStringencryptRSA(String algorithm,Key key,String input)throwsException{// 创建加密对象// 参数表示加密算法Cipher cipher =Cipher.getInstance(algorithm);// 初始化加密// 第一个参数:加密的模式// 第二个参数:使用私钥进行加密
cipher.init(Cipher.ENCRYPT_MODE, key);// 私钥加密byte[] bytes = cipher.doFinal(input.getBytes());// 对密文进行Base64编码returnBase64.encode(bytes);}
Source
packagecom.artisan;importcom.sun.org.apache.xml.internal.security.utils.Base64;importorg.apache.commons.io.FileUtils;importjavax.crypto.Cipher;importjava.io.File;importjava.nio.charset.Charset;importjava.nio.charset.StandardCharsets;importjava.security.*;importjava.security.spec.PKCS8EncodedKeySpec;importjava.security.spec.X509EncodedKeySpec;/**
* @author 小工匠
* @version 1.0
* @mark: show me the code , change the world
*/publicclassKeyPairOperate{publicstaticvoidmain(String[] args)throwsException{// 加密算法String algorithm ="RSA";// 生成密钥对并保存在本地文件中generateKeyToFile(algorithm,"a.pub","a.pri");// 读取私钥PrivateKey privateKey =readPrivateKeyFromFile(algorithm,"a.pri");byte[] encoded = privateKey.getEncoded();String privateContent =Base64.encode(encoded);System.out.println("私钥内容:"+ privateContent);// 读取公钥PublicKey publicKey =readPublicKeyFromFile(algorithm,"a.pub");byte[] publicKeyEncoded = publicKey.getEncoded();String publicContent =Base64.encode(publicKeyEncoded);System.out.println("公钥内容:"+ publicContent);// 使用公钥私钥实现加解密String text ="小工匠的IT生活";System.out.println("原文:"+ text);String enc =encryptRSA(algorithm, publicKey, text);System.out.println("公钥加密后的数据:"+ enc);String plainText =decryptRSA(algorithm, privateKey, enc);System.out.println("私钥解密后的数据:"+ plainText);}/**
* 解密数据
*
* @param algorithm : 算法
* @param encrypted : 密文
* @param key : 密钥
* @return : 原文
* @throws Exception
*/publicstaticStringdecryptRSA(String algorithm,Key key,String encrypted)throwsException{// 创建加密对象// 参数表示加密算法Cipher cipher =Cipher.getInstance(algorithm);// 私钥进行解密
cipher.init(Cipher.DECRYPT_MODE, key);// 由于密文进行了Base64编码, 在这里需要进行解码byte[] decode =Base64.decode(encrypted);// 对密文进行解密,不需要使用base64,因为原文不会乱码byte[] bytes1 = cipher.doFinal(decode);returnnewString(bytes1);}/**
* 使用密钥加密数据
*
* @param algorithm : 算法
* @param input : 原文
* @param key : 密钥
* @return : 密文
* @throws Exception
*/publicstaticStringencryptRSA(String algorithm,Key key,String input)throwsException{// 创建加密对象// 参数表示加密算法Cipher cipher =Cipher.getInstance(algorithm);// 初始化加密// 第一个参数:加密的模式// 第二个参数:使用私钥进行加密
cipher.init(Cipher.ENCRYPT_MODE, key);// 私钥加密byte[] bytes = cipher.doFinal(input.getBytes());// 对密文进行Base64编码returnBase64.encode(bytes);}/**
* @param algorithm
* @param filePath
* @return
* @throws Exception
*/privatestaticPublicKeyreadPublicKeyFromFile(String algorithm,String filePath)throwsException{// 将文件内容转为字符串String publicKeyString =FileUtils.readFileToString(newFile(filePath),StandardCharsets.UTF_8);// 获取密钥工厂KeyFactory keyFactory =KeyFactory.getInstance(algorithm);// 构建密钥规范 进行Base64解码X509EncodedKeySpec spec =newX509EncodedKeySpec(Base64.decode(publicKeyString));// 生成公钥return keyFactory.generatePublic(spec);}/**
* @param algorithm
* @param filePath
* @return
* @throws Exception
*/privatestaticPrivateKeyreadPrivateKeyFromFile(String algorithm,String filePath)throwsException{// 从文件中读取私钥字符串String privateKeyString =FileUtils.readFileToString(newFile(filePath),StandardCharsets.UTF_8);// 进行Base64解码byte[] privateKeyEncoded =Base64.decode(privateKeyString);// 获取密钥工厂KeyFactory keyFactory =KeyFactory.getInstance(algorithm);// 构建密钥规范 进行Base64解码PKCS8EncodedKeySpec spec =newPKCS8EncodedKeySpec(Base64.decode(privateKeyString));return keyFactory.generatePrivate(spec);}/**
* 生成密钥对并保存在本地文件中
*
* @param algorithm : 算法
* @param pubPath : 公钥保存路径
* @param priPath : 私钥保存路径
* @throws Exception
*/privatestaticvoidgenerateKeyToFile(String algorithm,String pubPath,String priPath)throwsException{// 获取密钥对生成器KeyPairGenerator keyPairGenerator =KeyPairGenerator.getInstance(algorithm);// 获取密钥对KeyPair keyPair = keyPairGenerator.generateKeyPair();// 获取公钥PublicKey publicKey = keyPair.getPublic();// 获取私钥PrivateKey privateKey = keyPair.getPrivate();// 获取byte数组byte[] publicKeyEncoded = publicKey.getEncoded();byte[] privateKeyEncoded = privateKey.getEncoded();// 进行Base64编码String publicKeyString =Base64.encode(publicKeyEncoded);String privateKeyString =Base64.encode(privateKeyEncoded);// 保存文件FileUtils.writeStringToFile(newFile(pubPath), publicKeyString,Charset.forName("UTF-8"));FileUtils.writeStringToFile(newFile(priPath), privateKeyString,Charset.forName("UTF-8"));}}
版权归原作者 小小工匠 所有, 如有侵权,请联系我们删除。