对称加解密算法解析

简介: 一、概述 cryptosystem密码学系统分为私钥系统及公钥系统。 私钥系统:指加解密双方事先做了私有信息约定,采用对称密钥算法; 公钥系统:指发送方用公开凭证对数据进行加密后传输,接收方使用私有凭证进行解密,采用非对称密钥算法; 对称加密分类 流加密(stream cipher),加密和解密双方使用相同伪随机加密数据流,一般都是逐位异或或者随机置换数据内容,常见的流加密算法如RC4。

一、概述

cryptosystem密码学系统分为私钥系统及公钥系统。

私钥系统:指加解密双方事先做了私有信息约定,采用对称密钥算法; 
公钥系统:指发送方用公开凭证对数据进行加密后传输,接收方使用私有凭证进行解密,采用非对称密钥算法;

对称加密分类

流加密(stream cipher),加密和解密双方使用相同伪随机加密数据流,一般都是逐位异或或者随机置换数据内容,常见的流加密算法如RC4。 
分组加密加密(block cipher),也叫块加密,将明文分成多个等长的模块(block),使用确定的算法和对称密钥对每组分别加密解密。 
高级的分组加密建立以迭代的方式产生密文,每轮产生的密文都使用不同的子密钥,而子密钥生成自原始密钥。 
数据加密中分组方式成为分组模式,如ECB;当加密中数据长度不足以满足分组时需要进行填充,此时采用的方式对应填充算法,如PKCS5Padding。

二、对称密钥算法

DES

Data Encryption Standard,数据加密标准,由IBM研究设计。 
密钥长度8字节,有效位56bit;其中,分组为64bit=8字节。

3DES

DES像 AES过渡的加密标准。 
由3个64bit的DES密钥对数据进行三次加密。 
密钥长度为24字节,有效位168bit。

AES

Advanced Encryption Standard,高级加密标准。 
包括AES-128;AES-192;AES-256算法,分组大小为128bit=16字节。

三、密码分组模式

1 ECB

Electronic Code Book,电码本模式 
相同分组输出相同的密钥,简单且利于并行运算,但无法隐藏模式,也容易招致攻击

2 CBC

Cipher Block Chaining,密文分组链模式 
需要初始化向量IV(长度与分组大小相同),第一组的密文与第二组数据XOR计算后再进行加密产生第二组密文 
安全性较好,TLS、IPSec等标准的推荐模式,但不利于并行运算

3 CFB

Cipher Feedback,密文反馈模式 

4 OFB

Output Feedback (OFB),输出反馈模式 

三、填充算法

1 NoPadding,无填充算法,通常要求数据满足分组长度要求; 
2 ZerosPadding,全部填充为0; 
3 PKCS5Padding,填充字节数; 
4 others…

DES像 AES过渡的加密标准 
由3个64bit的DES密钥对数据进行三次加密 
密钥长度为24字节,有效位168bit

 

四、代码示例

/**
 * 加密工具类
 * 
 * <pre>
 * AES支持128/192/256,取决于密钥长度(与位数对应)
 * DES密钥长度8字节
 * 3DES密钥长度24字节
 * 
 * 采用CBC 需指定初始向量IV,长度与分组大小相同
 * DES为8字节;AES为16字节
 * 
 * </pre>
 */
public class Crypto {
    static {
        // add bouncycastle support for md4 etc..
        Security.addProvider(new BouncyCastleProvider());
    }
    public static enum CryptType {
        DES_ECB_PKCS5("DES/ECB/PKCS5Padding"),
        DES_CBC_PKCS5("DES/CBC/PKCS5Padding", 8),
        DESede_ECB_PKCS5("DESede/ECB/PKCS5Padding"),
        DESede_CBC_PKCS5("DESede/CBC/PKCS5Padding", 8),
        AES_ECB_PKCS5("AES/CBC/PKCS5Padding", 16),
        AES_CBC_PKCS5("AES/CBC/PKCS5Padding", 16),
        AES_CBC_PKCS7("AES/CBC/PKCS7Padding", 16);
        public final String algorithm;
        public final String keyAlg;
        public final int ivlen;
        private CryptType(String algorithm, int ivlen) {
            this.algorithm = algorithm;
            this.keyAlg = this.algorithm.substring(0, this.algorithm.indexOf('/'));
            this.ivlen = ivlen;
        }
        private CryptType(String algorithm) {
            this(algorithm, 0);
        }
        @Override
        public String toString() {
            return this.algorithm;
        }
    }
    /**
     * Initialize the key
     * 
     * @param type
     * @return
     */
    public static String initKey(CryptType type) {
        try {
            KeyGenerator generator = KeyGenerator.getInstance(type.keyAlg);
            SecretKey secretKey = generator.generateKey();
            byte[] key = secretKey.getEncoded();
            return Codec.byteToHexString(key);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * generate default ivparam for type
     * 
     * @return
     */
    public static byte[] generateDefaultIv(CryptType type) {
        byte[] iv = new byte[type.ivlen];
        for (int i = 0; i < iv.length; i++) {
            iv[i] = 0x01;
        }
        return iv;
    }
    /**
     * Encrypt the value with the encryption standard.
     * 
     * @param value
     *            raw string
     * @param key
     *            in hex format
     * @param iv
     *            in hex format if exist
     * @param type
     * @return result in hex format
     */
    public static String encrypt(String value, String key, String iv, CryptType type) {
        byte[] dvalue;
        try {
            dvalue = value.getBytes("utf-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        byte[] dkey = Codec.hexStringToByte(key);
        byte[] div = null;
        if (iv != null && iv.length() > 0) {
            div = Codec.hexStringToByte(iv);
        }
        byte[] result = encrypt(dvalue, dkey, div, type);
        return Codec.byteToHexString(result);
    }
    /**
     * Encrypt the value with the encryption standard.
     * 
     * <pre>
     * key must have the corresponding length.
     * 
     * if use cbc mode which need iv param, the iv must not be null,
     * and iv data length is 16 for aes, 8 for des
     * 
     * </pre>
     * 
     * @param value
     * @param key
     * @param iv
     * @return
     */
    public static byte[] encrypt(byte[] value, byte[] key, byte[] iv, CryptType type) {
        try {
            SecretKeySpec skeySpec = new SecretKeySpec(key, type.keyAlg);
            Cipher cipher = Cipher.getInstance(type.algorithm);
            IvParameterSpec ivparamSpec = null;
            if (iv != null) {
                ivparamSpec = new IvParameterSpec(iv);
            }
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivparamSpec);
            return cipher.doFinal(value);
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
    /**
     * Encrypt the value with the encryption standard.
     * 
     * @param value
     *            encoded data in hex format
     * @param key
     *            in hex format
     * @param iv
     *            in hex format if exist
     * @param type
     * @return result raw string
     */
    public static String decrypt(String value, String key, String iv, CryptType type) {
        byte[] dvalue = Codec.hexStringToByte(value);
        byte[] dkey = Codec.hexStringToByte(key);
        byte[] div = null;
        if (iv != null && iv.length() > 0) {
            div = Codec.hexStringToByte(iv);
        }
        byte[] result = decrypt(dvalue, dkey, div, type);
        try {
            return new String(result, "utf-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * Decrypt the value with the encryption standard.
     * 
     * <pre>
     * key must have the corresponding length.
     * 
     * if use cbc mode which need iv param, the iv must not be null,
     * and iv data length is 16 for aes, 8 for des
     * 
     * </pre>
     * 
     * @param value
     * @param key
     * @param iv
     * @param type
     * @return
     */
    public static byte[] decrypt(byte[] value, byte[] key, byte[] iv, CryptType type) {
        try {
            SecretKeySpec skeySpec = new SecretKeySpec(key, type.keyAlg);
            Cipher cipher = Cipher.getInstance(type.algorithm);
            IvParameterSpec ivparamSpec = null;
            if (iv != null) {
                ivparamSpec = new IvParameterSpec(iv);
            }
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivparamSpec);
            return cipher.doFinal(value);
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}

 

key 长度受限问题

Exception in thread "main" java.security.InvalidKeyException: Illegal key size or default parameters

问题原因:因软件出版政策原因,默认 jdk 环境做了限制,当AES加密密钥大于128位时,会出现以上异常; 
解决办法:下载JCE扩展,替换至 ${java_home}/jre/lib/security 
http://www.oracle.com/technetwork/java/javase/downloads/index.html

五、参考文档:

http://m.blog.csdn.net/article/details?id=51066799 
http://www.blogjava.net/amigoxie/archive/2014/07/06/415503.html

img_9b09a36f6de95886f52ce82fa1e89c88.jpe

作者: zale

出处: http://www.cnblogs.com/littleatp/, 如果喜欢我的文章,请关注我的公众号

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出 原文链接  如有问题, 可留言咨询.

目录
相关文章
|
4月前
|
存储 算法 安全
如何控制上网行为——基于 C# 实现布隆过滤器算法的上网行为管控策略研究与实践解析
在数字化办公生态系统中,企业对员工网络行为的精细化管理已成为保障网络安全、提升组织效能的核心命题。如何在有效防范恶意网站访问、数据泄露风险的同时,避免过度管控对正常业务运作的负面影响,构成了企业网络安全领域的重要研究方向。在此背景下,数据结构与算法作为底层技术支撑,其重要性愈发凸显。本文将以布隆过滤器算法为研究对象,基于 C# 编程语言开展理论分析与工程实践,系统探讨该算法在企业上网行为管理中的应用范式。
132 8
|
4月前
|
存储 监控 算法
解析公司屏幕监控软件中 C# 字典算法的数据管理效能与优化策略
数字化办公的时代背景下,企业为维护信息安全并提升管理效能,公司屏幕监控软件的应用日益普及。此软件犹如企业网络的 “数字卫士”,持续记录员工电脑屏幕的操作动态。然而,伴随数据量的持续增长,如何高效管理这些监控数据成为关键议题。C# 中的字典(Dictionary)数据结构,以其独特的键值对存储模式和高效的操作性能,为公司屏幕监控软件的数据管理提供了有力支持。下文将深入探究其原理与应用。
89 4
|
5月前
|
机器学习/深度学习 监控 算法
员工上网行为监控软件中基于滑动窗口的C#流量统计算法解析​
在数字化办公环境中,员工上网行为监控软件需要高效处理海量网络请求数据,同时实时识别异常行为(如高频访问非工作网站)。传统的时间序列统计方法因计算复杂度过高,难以满足低延迟需求。本文将介绍一种基于滑动窗口的C#统计算法,通过动态时间窗口管理,实现高效的行为模式分析与流量计数。
127 2
|
7月前
|
存储 算法 安全
.NET 平台 SM2 国密算法 License 证书生成深度解析
授权证书文件的后缀通常取决于其编码格式和具体用途。本文档通过一个示例程序展示了如何在 .NET 平台上使用国密 SM2 算法生成和验证许可证(License)文件。该示例不仅详细演示了 SM2 国密算法的实际应用场景,还提供了关于如何高效处理大规模许可证文件生成任务的技术参考。通过对不同并发策略的性能测试,开发者可以更好地理解如何优化许可证生成流程,以满足高并发和大数据量的需求。 希望这段描述更清晰地传达了程序的功能和技术亮点。
741 14
.NET 平台 SM2 国密算法 License 证书生成深度解析
|
4月前
|
存储 监控 算法
内网监控桌面与 PHP 哈希算法:从数据追踪到行为审计的技术解析
本文探讨了内网监控桌面系统的技术需求与数据结构选型,重点分析了哈希算法在企业内网安全管理中的应用。通过PHP语言实现的SHA-256算法,可有效支持软件准入控制、数据传输审计及操作日志存证等功能。文章还介绍了性能优化策略(如分块哈希计算和并行处理)与安全增强措施(如盐值强化和动态更新),并展望了哈希算法在图像处理、网络流量分析等领域的扩展应用。最终强调了构建完整内网安全闭环的重要性,为企业数字资产保护提供技术支撑。
126 2
|
5月前
|
存储 监控 算法
员工电脑监控场景下 Python 红黑树算法的深度解析
在当代企业管理范式中,员工电脑监控业已成为一种广泛采用的策略性手段,其核心目标在于维护企业信息安全、提升工作效能并确保合规性。借助对员工电脑操作的实时监测机制,企业能够敏锐洞察潜在风险,诸如数据泄露、恶意软件侵袭等威胁。而员工电脑监控系统的高效运作,高度依赖于底层的数据结构与算法架构。本文旨在深入探究红黑树(Red - Black Tree)这一数据结构在员工电脑监控领域的应用,并通过 Python 代码实例详尽阐释其实现机制。
108 7
|
5月前
|
存储 监控 算法
基于 C++ 哈希表算法的局域网如何监控电脑技术解析
当代数字化办公与生活环境中,局域网的广泛应用极大地提升了信息交互的效率与便捷性。然而,出于网络安全管理、资源合理分配以及合规性要求等多方面的考量,对局域网内计算机进行有效监控成为一项至关重要的任务。实现局域网内计算机监控,涉及多种数据结构与算法的运用。本文聚焦于 C++ 编程语言中的哈希表算法,深入探讨其在局域网计算机监控场景中的应用,并通过详尽的代码示例进行阐释。
113 4
|
5月前
|
存储 算法 物联网
解析局域网内控制电脑机制:基于 Go 语言链表算法的隐秘通信技术探究
数字化办公与物联网蓬勃发展的时代背景下,局域网内计算机控制已成为提升工作效率、达成设备协同管理的重要途径。无论是企业远程办公时的设备统一调度,还是智能家居系统中多设备间的联动控制,高效的数据传输与管理机制均构成实现局域网内计算机控制功能的核心要素。本文将深入探究 Go 语言中的链表数据结构,剖析其在局域网内计算机控制过程中,如何达成数据的有序存储与高效传输,并通过完整的 Go 语言代码示例展示其应用流程。
98 0
|
6月前
|
监控 算法 安全
基于 C# 的内网行为管理软件入侵检测算法解析
当下数字化办公环境中,内网行为管理软件已成为企业维护网络安全、提高办公效率的关键工具。它宛如一位恪尽职守的网络守护者,持续监控内网中的各类活动,以确保数据安全及网络稳定。在其诸多功能实现的背后,先进的数据结构与算法发挥着至关重要的作用。本文将深入探究一种应用于内网行为管理软件的 C# 算法 —— 基于二叉搜索树的入侵检测算法,并借助具体代码例程予以解析。
103 4
|
6月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

热门文章

最新文章

推荐镜像

更多
  • DNS