逆向加密算法盘点与实例汇总
每次都要现查例子,先进行总结一篇。
单向加密
MD5
SHA
双向加密
非对称加密
RSA加密
RSA加密算法是一种非对称加密算法,所谓非对称,就是指该算法加密和解密使用不同的密钥,即使用加密密钥进行加密、解密密钥进行解密。在RAS算法中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,由于无法计算出大数n的欧拉函数phi(N),所以不能根据PK计算出SK。
也就是说,对极大整数做因数分解的难度决定了RSA算法的可靠性。理论上,只要其钥匙的长度n足够长,用RSA加密的信息实际上是不能被解破的。
RSA算法通常是先生成一对RSA密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开。为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位。这就使加密的计算量很大。为减少计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。对方收到信息后,用不同的密钥解密并可核对信息摘要。
公钥类型
特性 | XML 格式 | PEM 格式 |
---|---|---|
外观 | 纯文本,具有明显的 XML 标签(如 <RSAKeyValue> , <Modulus> ) | 纯文本,具有明显的 -----BEGIN XXX----- 和 -----END XXX----- 标签 |
编码方式 | 通常使用 Base64 编码密钥参数(模数、指数等) | 通常是 Base64 编码的 DER(二进制)数据,也可以是纯二进制 DER |
常见扩展名 | .xml | .pem , .key , .crt , .cer (注意:.crt /.cer 通常用于证书) |
标准/起源 | 主要由 微软 .NET 生态系统使用和推广 | 源于 OpenSSL 工具集,是互联网和 *nix 世界的事实标准 |
包含内容 | 非常明确地将密钥的每个组成部分(Modulus, Exponent, P, Q 等)分开存储 | 一个封装容器,可以包含: - 私钥 - 公钥 - X.509 证书 - CSR(证书签名请求) |
可读性 | 对开发者非常友好,结构清晰,易于解析和手动查看 | 需要借助 openssl 等工具解析内容才能看清详细参数 |
互操作性 | 主要在 Windows/.NET 环境中流行,其他平台需要特定库解析 | 通用性极强,被几乎所有开源库、语言和平台(如 Python, Java, Node.js, Go, PHP)广泛支持 |
1. XML 格式
这种格式将 RSA 密钥的每个数学组成部分都分解成独立的 XML 元素,并用 Base64 编码其值。
公钥示例:
<RSAKeyValue> <Modulus>xyz123...Abc=</Modulus> <!-- 模数 (n) --> <Exponent>AQAB</Exponent> <!-- 公钥指数 (e),通常是 65537 --> </RSAKeyValue>
私钥示例 (包含更多参数):
<RSAKeyValue> <Modulus>... </Modulus> <Exponent>... </Exponent> <P>... </P> <!-- 质数 p --> <Q>... </Q> <!-- 质数 q --> <DP>... </DP> <!-- d mod (p-1) --> <DQ>... </DQ> <!-- d mod (q-1) --> <InverseQ>... </InverseQ> <!-- (q^{-1} mod p) --> <D>... </D> <!-- 私钥指数 (d) --> </RSAKeyValue>
- 特点:优点:结构清晰,可读性强,非常适合在配置文件中使用或在不同 .NET 服务间传递。缺点:在非 Windows 生态系统中不如 PEM 通用。
2. PEM 格式
PEM (Privacy-Enhanced Mail) 格式本质上是一个 文本化的容器,它使用 Base64 编码来包装二进制数据(通常是 DER 编码的 ASN.1 结构),并加上明确的首尾行标签。
公钥示例:
-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A... ...(Base64 编码数据)... -----END PUBLIC KEY-----
私钥示例 (PKCS#8 格式):
-----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgw... ...(Base64 编码数据)... -----END PRIVATE KEY-----
传统的 PKCS#1 私钥格式:
-----BEGIN RSA PRIVATE KEY----- ...(Base64 编码数据)... -----END RSA PRIVATE KEY-----
实例
1.Csharp版本(.NET FRAMEWORK)
仅支持XML格式的公钥,PEM格式需要先调用RSAPublicKey进行转换
Main.cs
using System;
using Demo.Helper;
namespace RSADemo
{
class Program
{
static void Main(string[] args)
{
// 示例:PEM格式的公钥(通常以 -----BEGIN PUBLIC KEY----- 开头)
string pemPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx4b..." +
"(这里是完整的Base64编码PEM公钥内容,不包含首尾标签)";
// 1. 将PEM公钥转换为XML格式
string xmlPublicKey = RSAHelper.RSAPublicKey(pemPublicKey);
Console.WriteLine("XML格式公钥:\n" + xmlPublicKey);
// 2. 使用XML公钥加密数据
string plainText = "Hello, RSA加密测试!";
string encryptedText = RSAHelper.RSAEncrypt(xmlPublicKey, plainText);
Console.WriteLine("\n加密结果(Base64):\n" + encryptedText);
}
}
}
RSAHelper.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace Demo.Helper
{
/// <summary>
/// RSA工具类
/// </summary>
public class RSAHelper
{
/// <summary>
/// RSA公钥pem-->XML格式转换,
/// </summary>
/// <param name="publicKey">pem公钥</param>
/// <returns></returns>
public static string RSAPublicKey(string publicKey)
{
RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
string XML = string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
return XML;
}
/// <summary>
/// RSA公钥加密数据
/// </summary>
/// <param name="xmlPublicKey"></param>
/// <param name="content"></param>
/// <returns></returns>
public static string RSAEncrypt(string xmlPublicKey, string content)
{
string encryptedContent = string.Empty;
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.FromXmlString(xmlPublicKey);
byte[] encryptedData = rsa.Encrypt(Encoding.Default.GetBytes(content), false);
encryptedContent = Convert.ToBase64String(encryptedData);
}
return encryptedContent;
}
}
}
对称加密
AES加密
AES是高级加密标准,在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,目前已经被全世界广泛使用,同时AES已经成为对称密钥加密中最流行的算法之一。
AES支持三种长度的密钥:128位,192位,256位。
加密原理
1.密钥
密钥是AES算法实现加密和解密的根本。对称加密算法之所以对称,是因为这类算法对明文的加密和解密需要使用同一个密钥。
AES支持三种长度的密钥:
128位,192位,256位
平时大家所说的AES128,AES192,AES256,实际上就是指的AES算法对不同长度密钥的使用。
2.填充
要想了解填充的概念,我们先要了解AES的分组加密特性。什么是分组加密呢?我们来看看下面这张图:AES算法在对明文加密的时候,并不是把整个明文一股脑加密成一整段密文,而是把明文拆分成一个个独立的明文块,每一个明文块长度128bit。
这些明文块经过AES加密器的复杂处理,生成一个个独立的密文块,这些密文块拼接在一起,就是最终的AES加密结果。
假如一段明文长度是192bit,如果按每128bit一个明文块来拆分的话,第二个明文块只有64bit,不足128bit。这时候怎么办呢?就需要对明文块进行填充(Padding)。
填充涉及以下三种填充模式:
- NoPadding:
不做任何填充,但是要求明文必须是16字节的整数倍。
- PKCS5Padding(默认,是PKCS#7的子集):
如果明文块少于8 字节块(如 DES/3DES),在明文块末尾补足相应数量的字符,且每个字节的值等于缺少的字符数。
示例:明文 {1,2,3,4,5}
(5 字节),需补 3 字节 → {1,2,3,4,5,3,3,3}
。
- PKCS#7 Padding
若明文长度不是块大小的整数倍(如 AES 的 16 字节),则在末尾补 n
个字节,每个字节的值均为 n
。
示例:明文 {1,2,3,4,5,a,b,c,d,e}
(10 字节),需补 6 字节 → {1,2,3,4,5,a,b,c,d,e,6,6,6,6,6,6}
。
适用于块大小为 1~255 字节的算法(如 AES 的 16/24/32 字节块)。
是 PKCS#5 的通用化版本(PKCS#5 仅支持 8 字节块)。
- ISO10126Padding:
如果明文块少于16个字节(128bit),在明文块末尾补足相应数量的字节,最后一个字符值等于缺少的字符数,其他字符填充随机数。
比如明文:{1,2,3,4,5,a,b,c,d,e},缺少6个字节,则可能补全为{1,2,3,4,5,a,b,c,d,e,5,c,3,G,$,6}
加密模式
一、电码本模式(ECB)
将整个明文分成若干段相同的小段,然后对每一小段进行加密。
优点:操作简单,易于实现;分组独立,易于并行;误差不会被传送。——简单,可并行,不传送误差。
缺点:掩盖不了明文结构信息,难以抵抗统计分析攻击。——可对明文进行主动攻击。
二、密码分组链模式(CBC)
先将明文切分成若干小段,然后每一小段与初始块或者上一段的密文段进行异或运算后,再与密钥进行加密。
优点:能掩盖明文结构信息,保证相同密文可得不同明文,所以不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL和IPSec的标准。
缺点:(1)不利于并行计算;(2)传递误差——前一个出错则后续全错;(3)第一个明文块需要与一个初始化向量IV进行抑或,初始化向量IV的选取比较复杂。
初始化IV的选取方式:固定IV,计数器IV,随机IV(只能得到伪随机数,用的最多),瞬时IV(难以得到瞬时值)
三、输出反馈模式(OFB)
密码算法的输出(指密码key而不是密文)会反馈到密码算法的输入中,OFB模式并不是通过密码算法对明文直接加密,而是通过将明文分组和密码算法的输出进行XOR来产生密文分组。
优点:隐藏了明文模式;结合了分组加密和流密码(分组密码转化为流模式);可以及时加密传送小于分组的数据。
缺点:不利于并行计算;需要生成秘钥流;对明文的主动攻击是可能的。
四 计数器模式(CTR)
完全的流模式。将瞬时值与计数器连接起来,然后对此进行加密产生密钥流的一个密钥块,再进行XOR操作 。
优点:不泄露明文;仅需实现加密函数;无需填充;可并行计算。
缺点:需要瞬时值IV,难以保证IV的唯一性。
五.密码反馈模式(CFB)
把分组密码当做流密码使用,即密码反馈模式可将DES分组密码置换成流密码。流密码具有密文和明文长度一致、运行实时的性质,这样数据可以在比分组小得多的单元里进行加密。如果需要发送的每个字符长为8比特,就应使用8比特密钥来加密每个字符。如果长度超过8比特,则造成浪费。但是要注意,由于CFB模式中分组密码是以流密码方式使用,所以加密和解密操作完全相同,因此无法适用于公钥密码系统,只能适用于对称密钥密码系统。
密码反馈模式也需要一个初始量,无须保密,但对每条消息必须有一个不同的初始量。
优点:可以处理任意长度的消息,能适应用户不同数据格式的需要。可实现自同步功能。就有有限步的错误传播,除能获得保密性外,还可用于认证。
缺点:对信道错误较敏感,且会造成错误传播。数据加密的速率被降低。
AES算法流程
AES加密算法涉及4种操作:字节替代(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)和轮密钥加(AddRoundKey)。下图给出了AES加解密的流程,从图中可以看出:
1、解密算法的每一步分别对应加密算法的逆操作;
2、加解密所有操作的顺序正好是相反的。正是由于这几点(再加上加密算法与解密算法每步的操作互逆)保证了算法的正确性。加解密中每轮的密钥分别由种子密钥经过密钥扩展算法得到。算法中16字节的明文、密文和轮子密钥都以一个4x4的矩阵表示。
AddRoundKey (轮密钥加)— 矩阵中的每一个字节都与该次轮密钥(round key)做XOR运算;每个子密钥由密钥生成方案产生。
SubBytes(字节替代) — 通过非线性的替换函数,用查找表的方式把每个字节替换成对应的字节。
ShiftRows(行移位) — 将矩阵中的每个横列进行循环式移位。
MixColumns (列混淆)— 为了充分混合矩阵中各个直行的操作。这个步骤使用线性转换来混合每列的四个字节。
以上为AES在加密中的大致流程。
评论 (0)