首页 > 其他分享 >AES加密,全平台实现!

AES加密,全平台实现!

时间:2024-10-11 21:48:33浏览次数:11  
标签:AES 加密 String DD 平台 param data

前言

今天我们来聊聊数据加密与隐私相关话题。本人开发的加密工具,欢迎体验!https://www.pgyer.com/cryptotools 。AES加密,通俗的话来讲,就是用一个key把原数据变成一个新数据,也通过这个key还原成原数据。所以,它是一种对称的加密方式。只要别人不知道这个key,就无法解开数据的内容。它是DES加密的升级版本,由于AES的密钥长度更长,所以更安全。但是它的效率略有降低,不过这对于现代的计算机设备来说可以忽略不计。数字加密在当今数字时代的重要性不容忽视。

数字加密的重要性

数字加密的重要性,有以下几个主要方面:

  1. 数据保护:加密技术将信息转化为无法读取的格式,只有授权方可以解密。这是防止数据泄露的第一道防线,尤其在传输敏感信息(如个人身份信息、金融数据等)时尤为重要。
  2. 隐私保障:加密技术能够保护用户的隐私,确保通信双方之外的任何人无法窃听或截取对话内容。这在个人通信、电子邮件、社交媒体等领域非常关键。
  3. 安全通信:在互联网的应用中,许多协议(如HTTPS)依赖于加密来确保数据传输的安全性,防止中间人攻击和数据篡改。
  4. 身份验证:数字加密还用于验证身份,例如数字签名,确保发件人或设备的真实身份,防止身份冒用。
  5. 保护区块链和数字货币:加密技术是区块链和加密货币(如比特币)的核心,它确保了交易的安全性、不可篡改性和用户的匿名性。
  6. 防止数据篡改:加密不仅保护数据的机密性,还能通过散列函数(如SHA-256)等加密算法检测数据是否被篡改。这在文件验证、软件更新等场景中非常有用。

通过这些方式,数字加密在保障网络安全、数据隐私以及构建安全数字基础设施中起到了至关重要的作用。

AES加密介绍

AES(Advanced Encryption Standard,高级加密标准)是一种对称加密算法,用于加密和解密数据。AES 由美国国家标准与技术研究院(NIST)于2001年发布,成为取代DES(数据加密标准)的新加密标准。它广泛应用于政府、企业和个人数据保护中,特别是在金融、通信和网络安全领域。

AES的主要特点
  1. 对称加密

    • 同一密钥:AES是一种对称加密算法,这意味着加密和解密都使用相同的密钥。也就是说,发件人和接收人必须共享同一个密钥才能进行加密和解密。
  2. 加密块大小

    • 固定的块大小:AES处理的数据块大小是128位(16字节)。如果明文长度不足128位,AES使用填充方式(如PKCS7)补齐。
  3. 密钥长度

    • AES支持三种不同的密钥长度:128位、192位和256位。

      • AES-128:使用128位密钥,安全性高且速度较快。
      • AES-192:使用192位密钥。
      • AES-256:使用256位密钥,提供最高的安全性,但速度稍慢。
  4. 加密模式: AES加密常与不同的操作模式结合使用,常见的模式有:

    • ECB模式(电子密码本模式):每个块独立加密,不推荐使用,容易导致模式被破解。
    • CBC模式(密码分组链接模式):每个块的加密依赖于前一个块,常用于网络通信,确保数据的随机性。
    • CFB、OFB模式:这些模式常用于流加密或特殊场景。
  5. 安全性

    • AES算法基于复杂的代数结构,当前没有已知的高效攻击方法,即使使用现代计算机也无法在合理时间内破解。AES-256被认为是最安全的算法之一,适用于高安全性需求场景。
AES的应用
  • 数据加密:用于加密文件、数据库和存储设备,以保护敏感信息不被泄露。
  • 网络通信:广泛应用于TLS/SSL等加密协议,确保互联网通信的安全性(如HTTPS)。
  • 无线通信:Wi-Fi安全协议(如WPA2)使用AES加密,以确保无线网络传输数据的安全。
  • 区块链:加密货币和区块链技术中,也使用AES确保钱包和交易数据的安全。

AES加密因其高效、安全和标准化而成为当今广泛使用的加密技术,是保护个人隐私、企业数据和国家安全的基石。

AES加密中的重要概念

初始化向量(偏移量) / IV
加密方式
电子密码本 / ECB

ECB不需要偏移量iv

密码块连接 / CBC

在CBC中,每个明文块要先与前一个密文块进行异或后再加密,每个密文块都依赖于前面的所有明文块。

密文反馈 / CFB

CFB的加密跟解密过程几乎完全相同,注意它在解密过程中使用的是AES加密而不是AES解密。

输出反馈 / OFB

这个很简单,跟CFB128很相似,不同的是它是直接把输出块作为下一个块加密的输入块。

计数器模式 / CTR

COUNTER是整个CTR模式的核心所在。它是由IV经过一定的规则之后生成的一段数据,长度与数据块的长度相等。接着我们要选定一个数m,这个m是用于确定计数器中累加部分的大小的,通常取块大小的一半,块大小是奇数就四舍五入(当然对于AES并没有这个问题)。初始的计数器COUNTER1长度固定的任意一个随机字节序列,而不是像想象中那样一段随机数后面跟着一段0。

填充
NoPadding

顾名思义,就是不填充。缺点就是只能加密长为128bits倍数的信息,一般不会使用。

ZeroPadding

全部填充0x00,无论缺多少全部填充0x00,已经是128bits倍数仍要填充。

… | DD DD DD DD DD DD DD DD | DD DD DD DD 00 00 00 00 |

PKCS5和PKCS7

对于AES来说PKCS5Padding和PKCS7Padding是完全一样的,不同在于PKCS5限定了块大小为8bytes而PKCS7没有限定。因此对于AES来说两者完全相同,但是对于Rijndael就不一样了。AES是Rijndael在块大小为8bytes时的特例,对于使用其他信息块大小的Rijndael算法只能使用PKCS7。

在AES加密当中严格来说是不能使用pkcs5的,因为AES的块大小是16bytes而pkcs5只能用于8bytes,通常我们在AES加密中所说的pkcs5指的就是pkcs7。

… | DD DD DD DD DD DD DD DD | DD DD DD DD 04 04 04 04 |

ISO 10126

最后一个字节是填充的字节数(包括最后一字节),其他全部填随机数

… | DD DD DD DD DD DD DD DD | DD DD DD DD 81 A6 23 04 |

ANSI X9.23

跟ISO 10126很像,只不过ANSI X9.23其他字节填的都是0而不是随机数

… | DD DD DD DD DD DD DD DD | DD DD DD DD 00 00 00 04

AES加密的代码实现

Android&Java
/**
 * AES encryption.
 * 简体中文:AES加密。
 *
 * @param secretKey Key
 * @param transformation In the field of encryption, it usually refers to the combination
 *                       of encryption algorithms, modes, and padding.
 * @param iv Offset
 * @param data Data to be encrypted
 */
public static String encryptAES(String secretKey, String transformation, IvParameterSpec iv, String data) {
    try {
        Cipher cipher = Cipher.getInstance(transformation);
        cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(secretKey, AES), iv);
        byte[] encryptByte = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return base64Encode(encryptByte);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

/**
 * Encrypting with AES, using the default mode.
 * 简体中文:AES加密,使用默认的方式。
 *
 * @param secretKey  Key
 * @param data Data to be encrypted
 */
public static String encryptAES(String secretKey, String data) {
    try {
        Cipher cipher = Cipher.getInstance(AES_ECB_PKCS5);
        cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(secretKey, AES));
        byte[] encryptByte = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return base64Encode(encryptByte);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

/**
 * Decrypting with AES.
 * 简体中文:AES解密。
 *
 * @param secretKey  Key
 * @param transformation In the field of encryption, it usually refers to the combination
 *                       of encryption algorithms, modes, and padding.
 * @param iv Offset
 * @param base64Data Base64 data to be decrypted
 */
public static String decryptAES(String secretKey, String transformation, IvParameterSpec iv, String base64Data) {
    try {
        byte[] data = base64Decode(base64Data);
        Cipher cipher = Cipher.getInstance(transformation);
        cipher.init(Cipher.DECRYPT_MODE, getSecretKey(secretKey, AES), iv);
        byte[] result = cipher.doFinal(data);
        return new String(result, StandardCharsets.UTF_8);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

/**
 * Decrypting using AES, using the default mode.
 * 简体中文:AES解密,使用默认的方式。
 *
 * @param secretKey  Key
 * @param base64Data Base64 data to be decrypted
 */
public static String decryptAES(String secretKey, String base64Data) {
    try {
        byte[] data = base64Decode(base64Data);
        Cipher cipher = Cipher.getInstance(AES_ECB_PKCS5);
        cipher.init(Cipher.DECRYPT_MODE, getSecretKey(secretKey, AES));
        byte[] result = cipher.doFinal(data);
        return new String(result, StandardCharsets.UTF_8);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

/**
 * Encrypting a file using AES.
 * 简体中文:对文件进行AES加密。
 *
 * @param srcFile Source encrypted file
 * @param dir     Storage path of the encrypted file
 * @param dstName Encrypted file name
 * @param secretKey  Key
 * @param transformation In the field of encryption, it usually refers to the combination
 *                       of encryption algorithms, modes, and padding.
 * @return Encrypted file
 */
public static File encryptFileAES(File srcFile, String dir, String dstName, String secretKey, String transformation) {
    try {
        File encryptFile = new File(dir, dstName);
        FileOutputStream outputStream = new FileOutputStream(encryptFile);
        Cipher cipher = initFileAESCipher(secretKey, transformation, Cipher.ENCRYPT_MODE);
        CipherInputStream cipherInputStream = new CipherInputStream(
                new FileInputStream(srcFile), cipher);
        byte[] buffer = new byte[1024 * 2];
        int len;
        while ((len = cipherInputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, len);
            outputStream.flush();
        }
        cipherInputStream.close();
        IoUtils.close(outputStream);
        return encryptFile;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

/**
 * Encrypting a file using AES, with the default mode.
 * 简体中文:AES加密文件,默认方式。
 *
 * @param srcFile Source encrypted file
 * @param dir     Storage path of the encrypted file
 * @param dstName Encrypted file name
 * @param secretKey  Key
 */
public static File encryptFileAES(File srcFile, String dir, String dstName, String secretKey) {
    return encryptFileAES(srcFile, dir, dstName, secretKey, AES_CFB_PKCS5);
}

/**
 * Encrypting a file using AES.
 * 简体中文:AES解密文件。
 *
 * @param srcFile Source encrypted file
 * @param dir        Storage path of the decrypted file
 * @param dstName Decrypted file name
 * @param secretKey  Key
 * @param transformation In the field of encryption, it usually refers to the combination
 *                       of encryption algorithms, modes, and padding.
 */
public static File decryptFileAES(File srcFile, String dir, String dstName, String secretKey, String transformation) {
    try {
        File decryptFile = new File(dir, dstName);
        Cipher cipher = initFileAESCipher(secretKey, transformation, Cipher.DECRYPT_MODE);
        FileInputStream inputStream = new FileInputStream(srcFile);
        CipherOutputStream cipherOutputStream = new CipherOutputStream(
                new FileOutputStream(decryptFile), cipher);
        byte[] buffer = new byte[1024 * 2];
        int len;
        while ((len = inputStream.read(buffer)) >= 0) {
            cipherOutputStream.write(buffer, 0, len);
            cipherOutputStream.flush();
        }
        IoUtils.close(cipherOutputStream, inputStream);
        return decryptFile;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

/**
 * Decrypting a file using AES, with the default mode.
 * 简体中文:AES解密文件,默认方式。
 *
 * @param srcFile Source encrypted file
 * @param dir        Storage path of the decrypted file
 * @param dstName Decrypted file name
 * @param secretKey  Key
 */
public static File decryptFileAES(File srcFile, String dir, String dstName, String secretKey) {
    return decryptFileAES(srcFile, dir, dstName, secretKey, AES_CFB_PKCS5);
}

/**
 * Initialize AES Cipher.
 * 简体中文:初始化AES Cipher。
 *
 * @param secretKey  Key
 * @param transformation In the field of encryption, it usually refers to the combination
 *                       of encryption algorithms, modes, and padding.
 * @param cipherMode Encryption mode
 * @return Cryptographic Algorithm
 */
private static Cipher initFileAESCipher(String secretKey, String transformation, int cipherMode) {
    try {
        SecretKeySpec secretKeySpec = getSecretKey(secretKey, AES);
        Cipher cipher = Cipher.getInstance(transformation);
        cipher.init(cipherMode, secretKeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()]));
        return cipher;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

Java的AES加解密是JDK的内置模块,以上是我Java代码的封装,支持加密文本和文件,工具类在https://github.com/dora4/dora 也可以找到。

iOS
#import <CommonCrypto/CommonCryptor.h>
#import <Foundation/Foundation.h>

@interface AESCrypto : NSObject

+ (NSData *)AES256EncryptWithKey:(NSString *)key data:(NSData *)data;
+ (NSData *)AES256DecryptWithKey:(NSString *)key data:(NSData *)data;

@end

@implementation AESCrypto

+ (NSData *)AES256EncryptWithKey:(NSString *)key data:(NSData *)data {
    return [self AES256Operation:kCCEncrypt key:key data:data];
}

+ (NSData *)AES256DecryptWithKey:(NSString *)key data:(NSData *)data {
    return [self AES256Operation:kCCDecrypt key:key data:data];
}

+ (NSData *)AES256Operation:(CCOperation)operation key:(NSString *)key data:(NSData *)data {
    char keyPtr[kCCKeySizeAES256+1]; // 密钥长度(256位 = 32字节)
    bzero(keyPtr, sizeof(keyPtr)); // 初始化keyPtr
    
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; // 将密钥转换为C字符串

    size_t dataOutAvailable = data.length + kCCBlockSizeAES128; // 输出缓冲区大小
    void *dataOut = malloc(dataOutAvailable); // 分配内存
    size_t dataOutMoved = 0; // 实际加密数据的大小

    // 执行AES加密/解密
    CCCryptorStatus status = CCCrypt(operation,                  // 加密或解密操作
                                     kCCAlgorithmAES,             // 加密算法
                                     kCCOptionPKCS7Padding,       // 填充方式
                                     keyPtr,                      // 密钥
                                     kCCKeySizeAES256,            // 密钥长度
                                     NULL,                        // 初始向量(此处为nil)
                                     data.bytes,                  // 输入数据
                                     data.length,                 // 输入数据长度
                                     dataOut,                     // 输出缓冲区
                                     dataOutAvailable,            // 输出缓冲区大小
                                     &dataOutMoved);              // 输出大小

    if (status == kCCSuccess) {
        // 成功,返回加密后的数据
        return [NSData dataWithBytesNoCopy:dataOut length:dataOutMoved];
    }

    // 失败,释放内存并返回nil
    free(dataOut);
    return nil;
}

@end

iOS一般使用CommonCrypto进行AES的加解密。我们同样也定义成工具类,以AES256为例,定义两个类方法AES256EncryptWithKey和AES256DecryptWithKey。底层最终调用CCCrypt来实现加解密。

前端
import CryptoJS from "crypto-js";

static encryptAES(plainText) {
    const key = "12345678abcdefgh";
    const iv = '0000000000000000';
    const encodedContent = CryptoJS.enc.Utf8.parse(plainText);
    const keyUtf8 = CryptoJS.enc.Utf8.parse(key);
    const ivUtf8 = CryptoJS.enc.Utf8.parse(iv);
    const encrypted = CryptoJS.AES.encrypt(encodedContent, keyUtf8, {
        iv: ivUtf8,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });
    const cipherText = encrypted.toString();
    console.log(cipherText);
    return cipherText;
}

static decryptAES(cipherText) { 
    const key = "12345678abcdefgh"; 
    const iv = '0000000000000000'; 
    const keyUtf8 = CryptoJS.enc.Utf8.parse(key);
    const ivUtf8 = CryptoJS.enc.Utf8.parse(iv);
    const decrypted = CryptoJS.AES.decrypt(cipherText, keyUtf8, {
            iv: ivUtf8, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7
    });
    const decryptedText = decrypted.toString(CryptoJS.enc.Utf8); 
    console.log(decryptedText);
    return decryptedText;
}

前端通常使用CryptoJS库进行AES的加解密。人家都给你封装好了,直接调用即可。

注意事项

由于各个版本库的加密实现方式可能会不一样,所以加密出来的结果一般不会一样,但是解密出来都是相同的内容。如果你要加密出来也要一样,那我建议你用底层语言C/C++去写,然后打成动态链接库,供上层语言调用。或者使用诸如Flutter等跨平台/混合开发技术。另外推荐一个网页版的加解密工具 http://tool.chacuo.net/cryptaes ,支持的加解密方式贼多。

标签:AES,加密,String,DD,平台,param,data
From: https://blog.csdn.net/a_lwh____/article/details/142864172

相关文章

  • python+flask计算机毕业设计招聘平台(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景在当今竞争激烈的就业市场中,招聘平台作为连接求职者和企业的桥梁,发挥着至关重要的作用。随着互联网技术的飞速发展,传统的招聘方式已难以满......
  • python+flask计算机毕业设计证件办理资讯平台(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景在当今社会,证件办理是民众日常生活中不可或缺的一部分,涵盖了身份证、驾驶证、护照、营业执照等各类证件。然而,传统的证件办理流程繁琐复杂......
  • Gstreamer系列(2):gstreamer的视频编解码及不同平台编解码插件
    GStreamer是一个强大的多媒体框架,可以用于视频编码、解码和处理。视频编码的基础知识涉及到如何将原始视频数据转换为压缩格式以便于存储和传输。在GStreamer中,视频编码可以通过软编码(软件编码)和硬编码(硬件编码)两种方式实现。以下是GStreamer视频编码的基本概念,涵盖了这两......
  • [Java原创精品]基于Springboot+Vue的仿小红书博客论坛系统,社交媒体平台,含DFA敏感词过
    项目提供:完整源码+数据库sql文件+数据库表对应Excel文件项目获取看主......
  • 新版本重庆高校平台逆向解析
    cookie一共俩参数应该是有阿里云生成:测试后发现可以是固定值,估计是用来监控异常设备的_abfpc=8be8421a52dbf3581f5e75423587524390ffc509_2.0cna=060e2fa4d449bf9c160f7e5a77fe7ad3在登录请求中需要携带两个参数在header中:ts:当前时间戳SGsg:由三个参数字符串连接后md......
  • AMIS低代码平台,前端开发常见问题(样式篇 图片配置)
    关于样式问题在上篇中已经总结过了。这篇主要说下关于图片的引入。 1.页面上的图片引入。(1)将图片放入apps\bmc\page\bmc-page-config\image目录下。(2)在静态资源中引入,如下图: (3)在图片控件地址栏中引入也可以直接在地址栏中写入图片路径   2.背景图片的处理对于背......
  • 自动化分析背后,一站式数据分析平台!
    自动化分析背后,一站式数据分析平台!前言一站式数据分析平台前言在如今的企业管理中,数据已经不再是简单的存储和备份,而是成为了决策的核心驱动力。尤其是在面对海量数据的情况下,企业急需一个能够高效处理、分析、整合和呈现数据的工具。而这正是一站式数据分析平台应......
  • 1.7k star,一款网页版的跨平台远程控制和监控神器,附下载链接。
    今天给大家介绍一个免费、安全、开源、基于网页、跨平台且功能丰富的远程管理工具,可以通过浏览器,随时随地管理设备。工具下载链接下载链接:工具下载介绍Spark是一个Go编写的,网页UI、跨平台以及多功能的远程控制和监控工具,你可以随时随地监控和控制所有设备。亮点:本......
  • 安卓APK资源混淆加密重签名工具1.8.1更新 - 新增资源防解压功能, 优化大文件处理
    安卓APK资源混淆加密重签名工具,可以加固APK文件,对APK资源文件进行加密混淆处理,主要包含DEX代码混淆加密,字符串加密,Assets文件加密,防止反编译等功能,可以有效保护APK的内部代码和资源,防止APK被解包,逆向分析等.主要特性和功能点 1.支持修改APP基本信息,包括APP......
  • 微信小程序的北京旅游古建筑文化景点打卡平台Thinkphp/Laravel
    目录技术栈和环境说明项目介绍具体实现截图文件解析微信开发者工具HBuilderX+uniapp开发技术简介性能/安全/负载方面数据访问方式PHP核心代码部分展示代码目录结构解析系统测试详细视频演示源码获取技术栈和环境说明Laravel以其优雅的语法和快速开发能力著称,简化了......