调用博主最近登录时间
生活中的HYGGE
逆向加密算法盘点与实例汇总

逆向加密算法盘点与实例汇总

hygge
2025-09-03 / 0 评论 / 2 阅读 / 正在检测是否收录...

逆向加密算法盘点与实例汇总

每次都要现查例子,先进行总结一篇。

单向加密

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)。

填充涉及以下三种填充模式:

mf3pqg7r.png

  • 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的矩阵表示。

mf3pqr9s.png

AddRoundKey (轮密钥加)— 矩阵中的每一个字节都与该次轮密钥(round key)做XOR运算;每个子密钥由密钥生成方案产生。

SubBytes(字节替代) — 通过非线性的替换函数,用查找表的方式把每个字节替换成对应的字节。

ShiftRows(行移位) — 将矩阵中的每个横列进行循环式移位。

MixColumns (列混淆)— 为了充分混合矩阵中各个直行的操作。这个步骤使用线性转换来混合每列的四个字节。

以上为AES在加密中的大致流程。

DES加密

0

评论 (0)

取消