分组对称密钥加密算法——DES、3DES(DESede 或 TDES)、AES

一、常用的 "分组对称密钥加密算法" 分为以下3种

(1)DES(Data Encryption Standard,标准加密算法)

  1977年1月,美国政府颁布:采纳IBM公司设计的方案作为非机密数据的正式数据加密标准(DES Data Encryption Standard) 。

        DES采用了64位的分组长度和56位的密钥长度,它将64位的输入经过一系列变换得到64位的输出。解密则使用了相同的步骤和相同的密钥。DES的密钥长度为64位,由于第n*8(n=1,2,…8)是校验位,因此实际参与加密的长度为56位,密钥空间含有2^56个密钥。

(2)3DES(Triple Data Encryption Standard,三重标准加密算法)

  3DES是DES加密算法的一种模式,它使用3条64位的密钥对数据进行三次加密。数据加密标准(DES)是美国的一种由来已久的加密标准,它使用对称密钥加密法。

  3DES(即Triple DES)是DES向AES过渡的加密算法(1999年,NIST将3-DES指定为过渡的加密标准),是DES的一个更安全的变形。它是以DES为基本模块,通过组合分组方法设计出分组加密算法。

(3)AES(Advantaged Encryption Standard,高级加密算法)

  AES是下一代的加密算法标准,速度快,安全级别高。

  AES算法基于排列和置换运算。排列是对数据重新进行安排,置换是将一个数据单元替换为另一个。

  AES使用几种不同的方法来执行排列和置换运算。AES是一个迭代的、对称密钥分组的密码,它可以使用128、192和256位密钥,并且用128位(16字节)分组加密和解密数据。

  与公共密钥加密使用密钥对不同,对称密钥加密使用相同的密钥加密和解密数据。通过分组密码返回的加密数据的位数与输入数据相同。迭代加密使用一个循环结构,在该循环中重复置换和替换输入数据。

二、安全性 DES < 3DES < AES

三、代码实现(Android版)

package com.chy.crypto;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

import android.text.TextUtils;
import android.util.Base64;

//由于加密时会自动填充到8字节(64bit),那么在我们进行字节数组到字串的转化过程中,可以把它填补的不可见字符改变了,所以解密时会导致异常,用base64解决
//对称加密
public class SymmetricalCrypto {
	private static final String CHARSET_NAME = "utf-8";
	private static final String algorithm = "AES";
	/*
	AES/CBC/NoPadding (128)
	AES/CBC/PKCS5Padding (128)
	AES/ECB/NoPadding (128)
	AES/ECB/PKCS5Padding (128)
	DES/CBC/NoPadding (56)
	DES/CBC/PKCS5Padding (56)
	DES/ECB/NoPadding (56)
	DES/ECB/PKCS5Padding (56)

	(DESede实际上是3-DES)
	DESede/CBC/NoPadding (168)
	DESede/CBC/PKCS5Padding (168)
	DESede/ECB/NoPadding (168)
	DESede/ECB/PKCS5Padding (168)
	*/
	private static final String transformation = "AES/ECB/PKCS7Padding";

	public static String encrypt(String content, String password) {
		if(TextUtils.isEmpty(content) || TextUtils.isEmpty(password)) {
			return null;
		}
		String result = null;
		try {
			SecretKeySpec key = new SecretKeySpec(getPaddingPwd(password), algorithm);
			Cipher cipher = Cipher.getInstance(transformation);
			cipher.init(Cipher.ENCRYPT_MODE, key);
			byte[] byteContent = content.getBytes(CHARSET_NAME);
			byte[] encryptContent = cipher.doFinal(byteContent);
			byte[] base64Content = Base64.encode(encryptContent, Base64.DEFAULT);
			result = new String(base64Content, Charset.forName(CHARSET_NAME));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}
		return result;
	}

	public static String decrypt(String content, String password) {
		if(TextUtils.isEmpty(content) || TextUtils.isEmpty(password)) {
			return null;
		}
		String result = null;
		try {
			SecretKeySpec key = new SecretKeySpec(getPaddingPwd(password), algorithm);
			Cipher cipher = Cipher.getInstance(transformation);
			cipher.init(Cipher.DECRYPT_MODE, key);
			byte[] base64Content = content.getBytes(Charset.forName(CHARSET_NAME));
			byte[] encryptContent = Base64.decode(base64Content, Base64.DEFAULT);
			byte[] byteResult = cipher.doFinal(encryptContent, 0, encryptContent.length);
			result = new String(byteResult, CHARSET_NAME);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}
		return result;
	}

	private static byte[] getPaddingPwd(String password) throws UnsupportedEncodingException {
		// 密码必须是16byte的整數倍
		byte[] src = password.getBytes(CHARSET_NAME);
		int left = src.length % 16;
		if (left != 0) {
			byte[] dest = new byte[src.length + 16 - left];
			// 目标数组中所有元素的值置0
			Arrays.fill(dest, (byte) 0);
			System.arraycopy(src, 0, dest, 0, src.length);
			return dest;
		}
		return src;
	}
}


  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用Java实现3DES和解的示例代码: ```java import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.util.Base64; public class TripleDesExample { public static void main(String[] args) throws Exception { // 生成随机密钥 byte[] keyBytes = new byte[24]; SecureRandom random = new SecureRandom(); random.nextBytes(keyBytes); SecretKeySpec key = new SecretKeySpec(keyBytes, "DESede"); // 明文 String plaintext = "This is a secret message."; // 加 Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); byte[] ivBytes = new byte[8]; random.nextBytes(ivBytes); IvParameterSpec iv = new IvParameterSpec(ivBytes); cipher.init(Cipher.ENCRYPT_MODE, key, iv); byte[] ciphertext = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8)); // 解 cipher.init(Cipher.DECRYPT_MODE, key, iv); byte[] decryptedPlaintext = cipher.doFinal(ciphertext); System.out.println("Key: " + Base64.getEncoder().encodeToString(keyBytes)); System.out.println("Plaintext: " + plaintext); System.out.println("Ciphertext: " + Base64.getEncoder().encodeToString(ciphertext)); System.out.println("Decrypted plaintext: " + new String(decryptedPlaintext, StandardCharsets.UTF_8)); } } ``` 输出结果: ``` Key: 2qoQdkfT+i6JgMgkPyJQbV5bTq55X15f Plaintext: This is a secret message. Ciphertext: 2g3Mz0qKxGfz7NzE9wWx3uUqD2kQpWQb3RZ1MZq2+1M= Decrypted plaintext: This is a secret message. ``` 注意:使用3DES算法需要使用Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files来解除限制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值