精华内容
下载资源
问答
  • 对称密码算法有哪些
    千次阅读
    2021-07-10 11:58:53

    1、几种对称性加密算法:AES,DES,3DES

    DES是一种分组数据加密技术(先将数据分成固定长度的小数据块,之后进行加密),速度较快,适用于大量数据加密,而3DES是一种基于DES的加密算法,使用3个不同密匙对同一个分组数据块进行3次加密,如此以使得密文强度更高。

    相较于DES和3DES算法而言,AES算法有着更高的速度和资源使用效率,安全级别也较之更高了,被称为下一代加密标准。
    2、几种非对称性加密算法:RSA,DSA,ECC

    RSA和DSA的安全性及其它各方面性能都差不多,而ECC较之则有着很多的性能优越,包括处理速度,带宽要求,存储空间等等。

    更多相关内容
  • 对称与非对称加密算法

    千次阅读 2021-01-12 11:09:33
    一、对称加密算法:常用的算法包括DES、3DES、AES、DESX、Blowfish、、RC4、RC5、RC6。 二、非对称加密算法:常见的非对称加密算法:RSA、DSA(数字签名用)、ECC(移动设备用)、Diffie-Hellman、El Gamal。 三、...

    一、对称加密算法 :常用的算法包括DES、3DES、AES、DESX、Blowfish、RC4、RC5、RC6。推荐用AES。

    二、非对称加密算法:常见的非对称加密算法:RSA、DSA(数字签名用)、ECC(移动设备用)、Diffie-Hellman、El Gamal。推荐用ECC(椭圆曲线密码编码学)。

    三、散列算法(Hash算法---单向加密算法):常见的Hash算法:MD2、MD4、MD5、HAVAL、SHA、SHA-1、HMAC、HMAC-MD5、HMAC-SHA1。推荐MD5、SHA-1。

    四、 加密算法的选择

    https://blog.csdn.net/liudongdong19/article/details/82217431

    展开全文
  • 常用的对称加密算法

    千次阅读 2019-10-26 17:20:38
    需要对加密和解密使用相同密钥的加密算法。由于其速度快,对称性加密通常在消息发送方需要加密大量数据时使用。对称性加密也称为密钥加密。 所谓对称,就是采用这种加密方法的双方使用方式用同样的密钥进行加密和...


    需要对加密和解密使用相同密钥的加密算法。由于其速度快,对称性加密通常在消息发送方需要加密大量数据时使用。对称性加密也称为密钥加密。

    所谓对称,就是采用这种加密方法的双方使用方式用同样的密钥进行加密和解密。密钥是控制加密及解密过程的指令。算法是一组规则,规定如何进行加密和解密。

    因此加密的安全性不仅取决于加密算法本身,密钥管理的安全性更是重要。因为加密和解密都使用同一个密钥,如何把密钥安全地传递到解密者手上就成了必须要解决的问题。

    在对称加密算法中常用的算法有:DES、3DES、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK等。

    下面列举几个比较常用的:

    1、DES(Data Encryption Standard)

    DES加密算法出自IBM的研究,后来被美国政府正式采用,之后开始广泛流传,但是近些年使用越来越少,因为DES使用56位(8字节)密钥,以现代计算能力,
    24小时内即可被破解。虽然如此,在某些简单应用中,我们还是可以使用DES加密算法

    特点:数据加密标准,速度较快,适用于加密大量数据的场合

    提供一个 DES 加密工具类:

    package com.blog.www.util.coder;
    
    import lombok.AccessLevel;
    import lombok.NoArgsConstructor;
    import lombok.NonNull;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.codec.DecoderException;
    import org.apache.commons.codec.binary.Hex;
    import org.apache.commons.lang3.StringUtils;
    
    import javax.crypto.*;
    import javax.crypto.spec.DESKeySpec;
    import javax.crypto.spec.IvParameterSpec;
    import java.security.InvalidAlgorithmParameterException;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.security.spec.InvalidKeySpecException;
    
    /**
     * DES 加密工具
     * <br/>
     * 参考:<a href='https://blog.csdn.net/bbaiggey/article/details/79414646'>java加解密之DES多种使用方式</a>
     * <br/>
     * DES加密介绍
     * <br/>
     * DES是一种对称加密算法,所谓对称加密算法即:加密和解密使用相同密钥的算法。DES加密算法出自IBM的研究,
     * 后来被美国政府正式采用,之后开始广泛流传,但是近些年使用越来越少,因为DES使用56位密钥,以现代计算能力,
     * 24小时内即可被破解。虽然如此,在某些简单应用中,我们还是可以使用DES加密算法,本文简单讲解DES的JAVA实现
     * 。
     * 注意:DES加密和解密过程中,密钥长度都必须是8的倍数
     */
    @Slf4j
    @NoArgsConstructor(access = AccessLevel.PRIVATE)
    public final class DESCoder {
    
    	/**
    	 * Cipher加密器初始化需要一个字符串,字符串里提供了三种设置。
    	 * 一是,加解密算法;二是,加解密模式;三是,是否需要填充。
    	 * <br/>
    	 * ECB(电码本模式),CBC(加密块链模式),OFB(输出反馈模式),CFB(加密反馈模式)
    	 */
    	private static final String CIPHER_ALGORITHM = "DES/CBC/PKCS5Padding";
    
    	private static final String ALGORITHM = "DES";
    
    
    	/**
    	 * 生成密钥
    	 *
    	 * @param seed 偶数种子
    	 */
    	public static String initDesKey(String seed) throws DecoderException, NoSuchAlgorithmException {
    		SecureRandom secureRandom;
    		if (StringUtils.isNotBlank(seed)) {
    			secureRandom = new SecureRandom(Hex.decodeHex(seed));
    		} else {
    			secureRandom = new SecureRandom();
    		}
    		// init key生成器
    		KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM);
    		kg.init(secureRandom);
    		// 生成一个Key
    		SecretKey secretKey = kg.generateKey();
    		// 转变为字节数组
    		byte[] encoded = secretKey.getEncoded();
    		// 生成密钥字符串
    		return Hex.encodeHexString(encoded);
    	}
    
    
    	/**
    	 * 加密
    	 *
    	 * @param data 原始数据
    	 * @param key  DES密钥 可使用 initDesKey() 方法获取,也可自定义(密钥长度都必须是8的倍数)
    	 * @return 加密后数据
    	 */
    	public static String encrypt(@NonNull final String data, @NonNull String key) throws InvalidKeyException,
    			InvalidKeySpecException, InvalidAlgorithmParameterException, NoSuchAlgorithmException,
    			NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {
    		// 创建一个DESKeySpec对象
    		DESKeySpec desKeySpec = createDesKeySpec(key);
    		Cipher cipher = getCipher(desKeySpec, Cipher.ENCRYPT_MODE);
    		// 现在,获取数据并加密
    		return Hex.encodeHexString(cipher.doFinal(data.getBytes())).toUpperCase();
    	}
    
    
    	/**
    	 * 解密
    	 *
    	 * @param data 待解密内容
    	 * @param key  DES密钥 可使用 initDesKey() 方法获取,也可自定义(密钥长度都必须是8的倍数)
    	 * @return 原始数据
    	 */
    	public static String decrypt(@NonNull final String data, @NonNull String key) throws InvalidKeyException,
    			InvalidKeySpecException, InvalidAlgorithmParameterException, NoSuchAlgorithmException,
    			NoSuchPaddingException, DecoderException, BadPaddingException, IllegalBlockSizeException {
    		// 创建一个DESKeySpec对象
    		DESKeySpec desKeySpec = createDesKeySpec(key);
    		Cipher cipher = getCipher(desKeySpec, Cipher.DECRYPT_MODE);
    		// 解密操作
    		return new String(cipher.doFinal(Hex.decodeHex(data)));
    	}
    
    
    	private static DESKeySpec createDesKeySpec(String key) throws InvalidKeyException {
    		// 创建一个DESKeySpec对象
    		return new DESKeySpec(key.getBytes());
    	}
    
    	private static Cipher getCipher(DESKeySpec desKeySpec, Integer mode) throws NoSuchAlgorithmException, InvalidKeySpecException,
    			NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException {
    		// 创建一个密匙工厂
    		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
    		// 将DESKeySpec对象转换成SecretKey对象
    		SecretKey secureKey = keyFactory.generateSecret(desKeySpec);
    		// Cipher对象实际完成解密操作
    		Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
    		// 用密匙初始化Cipher对象
    		cipher.init(mode, secureKey, new IvParameterSpec(desKeySpec.getKey()));
    		return cipher;
    	}
    }
    

    使用测试:

    /**
     * DES 加密测试
     */
    class DesTest {
    	public static void main(String[] args) {
    		try {
    			// 待加密字符
    			String originalStr = "七里香";
    			System.out.println(String.format("待加密字符: %s", originalStr));
    			String desKey = DESCoder.initDesKey("12345678");
    			System.out.println(String.format("密钥:%s", desKey));
    			String encrypt = DESCoder.encrypt(originalStr, desKey);
    			System.out.println(String.format("%s 加密结果:%s", originalStr, encrypt));
    			System.out.println(String.format("%s 解密结果:%s", originalStr, DESCoder.decrypt(encrypt, desKey)));
    		} catch (DecoderException | NoSuchAlgorithmException | InvalidKeyException | InvalidKeySpecException
    				| InvalidAlgorithmParameterException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException e) {
    			e.printStackTrace();
    		}
    	}
    }
    

    测试结果:

    20191026102555.png

    2、3DES(Triple DES)

    基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高

    3DES是三重数据加密,且可以逆推的一种算法方案。但由于3DES的算法是公开的,所以算法本身没有密钥可言,主要依靠唯一密钥来确保数据加解密的安全。到目前为止,仍没有人能破解3DES。

    3DES 加密工具类:

    package com.blog.www.util.coder;
    
    import lombok.AccessLevel;
    import lombok.NoArgsConstructor;
    import lombok.NonNull;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.codec.DecoderException;
    import org.apache.commons.codec.binary.Hex;
    import org.apache.commons.lang3.StringUtils;
    
    import javax.crypto.*;
    import javax.crypto.spec.DESedeKeySpec;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.security.spec.InvalidKeySpecException;
    
    /**
     * 3DES 加密工具
     * <br/>
     * 参考:<a href='https://www.cnblogs.com/shindo/p/6021976.html'>3DES加密算法</a>
     * <br/>
     * 3DES加密介绍
     * <br/>
     * 3DES是三重数据加密,且可以逆推的一种算法方案。
     * 但由于3DES的算法是公开的,所以算法本身没有密钥可言,
     * 主要依靠唯一密钥来确保数据加解密的安全。到目前为止,仍没有人能破解3DES。
     */
    @Slf4j
    @NoArgsConstructor(access = AccessLevel.PRIVATE)
    public final class DES3Coder {
    
    	/**
    	 * Cipher加密器初始化需要一个字符串,字符串里提供了三种设置。
    	 * 一是,加解密算法;二是,加解密模式;三是,是否需要填充。
    	 * <br/>
    	 * ECB(电码本模式),CBC(加密块链模式),OFB(输出反馈模式),CFB(加密反馈模式)
    	 */
    	private static final String CIPHER_ALGORITHM = "DESede/ECB/PKCS5Padding";
    
    	private static final String ALGORITHM = "DESede";
    
    
    	/**
    	 * 生成密钥
    	 *
    	 * @param seed 偶数种子
    	 */
    	public static String initKey(String seed) throws DecoderException, NoSuchAlgorithmException {
    		SecureRandom secureRandom;
    		if (StringUtils.isNotBlank(seed)) {
    			secureRandom = new SecureRandom(Hex.decodeHex(seed));
    		} else {
    			secureRandom = new SecureRandom();
    		}
    		// init key生成器
    		KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM);
    		kg.init(secureRandom);
    		// 生成一个Key
    		SecretKey secretKey = kg.generateKey();
    		// 转变为字节数组
    		byte[] encoded = secretKey.getEncoded();
    		// 生成密钥字符串
    		return Hex.encodeHexString(encoded);
    	}
    
    
    	/**
    	 * 加密
    	 *
    	 * @param data 原始数据
    	 * @param key  3DES密钥对象 使用 initKey() 方法获取,也可自定义,key长度必须是大于等于 3*8 = 24 位
    	 * @return 加密后数据
    	 */
    	public static String encrypt(@NonNull final String data, @NonNull String key) throws InvalidKeyException,
    			InvalidKeySpecException, NoSuchAlgorithmException,
    			NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {
    		// 创建一个DESKeySpec对象
    		DESedeKeySpec deSedeKeySpec = createDesKeySpec(key);
    		Cipher cipher = getCipher(deSedeKeySpec, Cipher.ENCRYPT_MODE);
    		// 现在,获取数据并加密
    		return Hex.encodeHexString(cipher.doFinal(data.getBytes())).toUpperCase();
    	}
    
    
    	/**
    	 * 解密
    	 *
    	 * @param data 待解密内容
    	 * @param key  3DES密钥对象 可使用 initKey() 方法获取,也可自定义,key长度必须是大于等于 3*8 = 24 位
    	 * @return 原始数据
    	 */
    	public static String decrypt(@NonNull final String data, @NonNull String key) throws InvalidKeyException,
    			InvalidKeySpecException, NoSuchAlgorithmException,
    			NoSuchPaddingException, DecoderException, BadPaddingException, IllegalBlockSizeException {
    		// 创建一个DESKeySpec对象
    		DESedeKeySpec deSedeKeySpec = createDesKeySpec(key);
    		Cipher cipher = getCipher(deSedeKeySpec, Cipher.DECRYPT_MODE);
    		// 解密操作
    		return new String(cipher.doFinal(Hex.decodeHex(data)));
    	}
    
    
    	/**
    	 * @param key 3DES 加密, key必须是长度大于等于 3*8 = 24 位
    	 * @return {@link DESedeKeySpec}
    	 * @throws InvalidKeyException invalidKeyException
    	 */
    	private static DESedeKeySpec createDesKeySpec(String key) throws InvalidKeyException {
    		// 创建一个 DESedeKeySpec 对象
    		return new DESedeKeySpec(key.getBytes());
    	}
    
    	private static Cipher getCipher(DESedeKeySpec deSedeKeySpec, Integer mode) throws NoSuchAlgorithmException, InvalidKeySpecException,
    			NoSuchPaddingException, InvalidKeyException {
    		// 创建一个密匙工厂
    		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
    		// 将 DESedeKeySpec 对象转换成 SecretKey 对象
    		SecretKey secureKey = keyFactory.generateSecret(deSedeKeySpec);
    		// Cipher对象实际完成解密操作
    		Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
    		// 用密匙初始化 Cipher对象
    		cipher.init(mode, secureKey);
    		return cipher;
    	}
    
    }
    

    3DES测试:

    /**
     * 3DES 加密测试
     */
    class Des3Test {
    	public static void main(String[] args) {
    		try {
    			// 待加密字符
    			String originalStr = "发如雪";
    			System.out.println(String.format("待加密字符: %s", originalStr));
    			String des3Key = DES3Coder.initKey("4545454545AAAA");
    			System.out.println(String.format("密钥:%s", des3Key));
    			String encrypt = DES3Coder.encrypt(originalStr, des3Key);
    			System.out.println(String.format("%s 加密结果:%s", originalStr, encrypt));
    			System.out.println(String.format("%s 解密结果:%s", originalStr, DES3Coder.decrypt(encrypt, des3Key)));
    		} catch (DecoderException | NoSuchAlgorithmException | InvalidKeyException | InvalidKeySpecException
    				| NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException e) {
    			e.printStackTrace();
    		}
    	}
    }
    

    测试结果:

    20191026105618.png

    3、AES(Advanced Encryption Standard)推荐使用

    密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。

    这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院 (NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一 [1] 。
    该算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,以Rijdael之名命之,投稿高级加密标准的甄选流程。(Rijdael的发音近于 “Rhine doll”。)

    高级加密标准,是下一代的加密算法标准,速度快,安全级别高,支持128、192、256、512位密钥的加密。

    AES 加密工具类

    package com.blog.www.util.coder.symmetry;
    
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.codec.DecoderException;
    import org.apache.commons.codec.binary.Hex;
    import org.apache.commons.lang3.StringUtils;
    
    import javax.crypto.*;
    import javax.crypto.spec.SecretKeySpec;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    
    /**
     * AES加密
     * <br/>
     * 介绍:
     * <br/>
     * 密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。
     * <br/>
     * 这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用。
     * 经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院 (NIST)于2001年11月26日发布于FIPS PUB 197,
     * 并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一
     * <br/>
     * 参考:
     * <ul>
     *     <li>
     *         <a href='【JAVA】AES加密 简单实现 AES-128/ECB/PKCS5Padding'>https://segmentfault.com/a/1190000015943620</a>
     *     </li>
     *     <li>
     *         <a href='Java加密技术(二)——对称加密算法DES&AES'>https://www.iteye.com/blog/snowolf-380034</a>
     *     </li>
     * </ul>
     * <p>
     * <br/>
     *
     * @author :leigq
     * @date :2019/8/8 17:20
     */
    @Slf4j
    public class AESCoder {
    
    	/**
    	 * Cipher加密器初始化需要一个字符串,字符串里提供了三种设置。
    	 * 一是,加解密算法;二是,加解密模式;三是,是否需要填充。
    	 * <br/>
    	 * ECB(电码本模式),CBC(加密块链模式),OFB(输出反馈模式),CFB(加密反馈模式)
    	 */
    	private static final String CIPHER_MODE = "AES/ECB/PKCS5Padding";
    
    	private static final String ALGORITHM = "AES";
    
    	/**
    	 * 生成密钥
    	 */
    	public static String initAesKey(String seed) throws NoSuchAlgorithmException, DecoderException {
    		SecureRandom secureRandom;
    		if (StringUtils.isNotBlank(seed)) {
    			secureRandom = new SecureRandom(Hex.decodeHex(seed));
    		} else {
    			secureRandom = new SecureRandom();
    		}
    		// init key生成器
    		KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM);
    		// 要生成多少位,只需要修改这里即可 128, 192 或 256,单位 bit
    		kg.init(128, secureRandom);
    		// 生成一个Key
    		SecretKey secretKey = kg.generateKey();
    		// 转变为字节数组
    		byte[] encoded = secretKey.getEncoded();
    		// 生成密钥字符串
    		return Hex.encodeHexString(encoded);
    	}
    
    	/**
    	 * AES加密
    	 *
    	 * @param data 待加密的数据
    	 * @param key  密钥
    	 * @return 加密后的数据
    	 */
    	public static String encrypt(String data, String key) {
    		try {
    			Cipher cipher = getCipher(key, Cipher.ENCRYPT_MODE);
    			return Hex.encodeHexString(cipher.doFinal(data.getBytes())).toUpperCase();
    		} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | DecoderException | IllegalBlockSizeException | BadPaddingException e) {
    			log.error("加密异常:", e);
    			return null;
    		}
    	}
    
    
    	/**
    	 * AES解密
    	 *
    	 * @param data 待解密的数据
    	 * @param key  密钥
    	 * @return 解密后的数据
    	 */
    	public static String decrypt(String data, String key) {
    		try {
    			Cipher cipher = getCipher(key, Cipher.DECRYPT_MODE);
    			return new String(cipher.doFinal(Hex.decodeHex(data)));
    		} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | DecoderException | IllegalBlockSizeException | BadPaddingException e) {
    			log.error("解密异常:", e);
    			return null;
    		}
    	}
    
    	private static Cipher getCipher(String key, Integer mode) throws NoSuchAlgorithmException,
    			NoSuchPaddingException, InvalidKeyException, DecoderException {
    		// 创建密匙
    		SecretKey secretKey = new SecretKeySpec(Hex.decodeHex(key), ALGORITHM);
    		// Cipher 对象实际完成解密操作
    		Cipher cipher = Cipher.getInstance(CIPHER_MODE);
    		// 用密匙初始化 Cipher 对象
    		cipher.init(mode, secretKey);
    		return cipher;
    	}
    
    }
    

    使用测试:

    /**
     * AES 加密测试
     */
    class AesTest {
    	public static void main(String[] args) {
    		try {
    			// 待加密字符
    			String originalStr = "美女,约吗?";
    			System.out.println(String.format("待加密字符: %s", originalStr));
    			String aesKey = AESCoder.initAesKey(null);
    			System.out.println(String.format("密钥:%s", aesKey));
    			String encrypt = AESCoder.encrypt(originalStr, aesKey);
    			System.out.println(String.format("%s 加密结果:%s", originalStr, encrypt));
    			System.out.println(String.format("%s 解密结果:%s", originalStr, AESCoder.decrypt(encrypt, aesKey)));
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    }
    

    测试结果:

    20191026152340.png

    展开全文
  • 主要介绍了Java 对称加密使用DES / 3DES / AES 这三种算法分别实现的相关资料,这里提供了实例代码,需要的朋友可以参考下
  • 在PHP的语法环境里,urlencode与urldecode,base64_encode和base64_decode自带的对称算法,不过这些自带的算法不能称之为加密算法,只能说是编码方式而已。可是我们可以利用这些来进行一些加工,来实现简单的加密和...
  • C语言实现国密SM4对称加解密算法。编译环境:VS2010。请参考我的博客https://blog.csdn.net/u013073067/article/details/86578753 分析代码
  • 常用的几种非对称加密算法

    万次阅读 2019-10-26 17:22:09
    相对对称加密而言,无需拥有同一组密钥,非对称加密是一种“信息公开的密钥交换协议”。非对称加密需要公开密钥和私有密钥两组密钥,公开密钥和私有密钥是配对起来的,也就是说使用公开密钥进行数据加密,只有对应的...


    相对对称加密而言,无需拥有同一组密钥,非对称加密是一种“信息公开的密钥交换协议”。非对称加密需要公开密钥和私有密钥两组密钥,公开密钥和私有密钥是配对起来的,也就是说使用公开密钥进行数据加密,只有对应的私有密钥才能解密。这两个密钥是数学相关,用某用户密钥加密后的密文,只能使用该用户的加密密钥才能解密。如果知道了其中一个,并不能计算出另外一个。因此如果公开了一对密钥中的一个,并不会危害到另外一个密钥性质。这里把公开的密钥为公钥,不公开的密钥为私钥。算法代表:RSA,DSA。

    RSA 能同时用于加密和数字签名,而DSA只能用于签名,本文重点讲解RSA。

    1、RSA(算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman)

    这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman。

    这种加密算法的特点主要是密钥的变化,上文我们看到DES只有一个密钥。相当于只有一把钥匙,如果这把钥匙丢了,数据也就不安全了。RSA同时有两把钥匙,公钥与私钥。同时支持数字签名。数字签名的意义在于,对传输过来的数据进行校验。确保数据在传输工程中不被修改。

    RSA 加密工具类:

    package com.blog.www.util.coder.asymmetrical;
    
    import com.blog.www.util.coder.base.BaseCoderUtils;
    import lombok.extern.slf4j.Slf4j;
    
    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.NoSuchPaddingException;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.UnsupportedEncodingException;
    import java.nio.charset.StandardCharsets;
    import java.security.*;
    import java.security.cert.CertificateException;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.InvalidKeySpecException;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    
    /**
     * RSA非对称加密解密工具类
     *
     * <p>
     * 这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。 算法的名字以发明者的名字命名:Ron
     * Rivest, AdiShamir 和Leonard Adleman。 这种加密算法的特点主要是密钥的变化,RSA同时有两把钥匙,公钥与私钥。
     * 同时支持数字签名。数字签名的意义在于,对传输过来的数据进行校验。确保数据在传输工程中不被修改。
     * <p>
     * 参考:
     * <br/>
     * <ul>
     *     <li><a href='https://www.iteye.com/blog/snowolf-381767'>Java加密技术(四)——非对称加密算法RSA</a></li>
     *     <li><a href='https://my.oschina.net/jiangli0502/blog/171263'>RSA加密解密及数字签名Java实现</a></li>
     * </ul>
     * <p>
     * <a href="https://github.com/wwwtyro/cryptico">前端demo<a> <br>
     * <br>
     */
    @Slf4j
    public class RSACoder {
    
    	/**
    	 * 填充方式。这里有【RSA/ECB/PKCS1Padding】填充(默认)和【RSA/ECB/NoPadding】填充两种可选。
    	 * <p>
    	 * 注意:使用填充时,公钥每次加密的字符串都会不一样,这样更安全;不使用则每次都一样。因为java默认是填充的,而安卓默认不填充,
    	 * 所以安卓默认加密的密文,java默认不能解密!!必须手动指定他们用一致的填充方式,才能正确加密解密。
    	 */
    	private static final String CIPHER_MODE = "RSA/ECB/PKCS1Padding";
    
    	/**
    	 * 算法类型
    	 */
    	private static final String ALGORITHM = "RSA";
    
    	/**
    	 * RSA密钥长度必须是64的倍数,在512~65536之间。默认是1024
    	 */
    	private static final int KEY_SIZE = 1024;
    
    	/**
    	 * 由公钥字节数组用Base64编码成的字符串,方便传播、储存
    	 */
    	private static final String PUB_KEY_BASE64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxKRX+P64kA0qrd3JYYZIZ5jam63DsAlx5PKlfC0hOAhJ3wfD2Bjl3CHKNMtEKwcnZlunvikOt7/7uKdVdxDYzwpU2ivwNXDA5kMPsx8prjwS7FsdCMWnOTGWBTCYeReFHWVmSj4KxYaOO7csPWBR0AhQX9qiPSWDEKcnH5YNiiQIDAQAB";
    
    	/**
    	 * 由私钥字节数组用Base64编码成的字符串,方便传播、储存
    	 */
    	private static final String PRI_KEY_BASE64 = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALEpFf4/riQDSqt3clhhkhnmNqbrcOwCXHk8qV8LSE4CEnfB8PYGOXcIco0y0QrBydmW6e+KQ63v/u4p1V3ENjPClTaK/A1cMDmQw+zHymuPBLsWx0Ixac5MZYFMJh5F4UdZWZKPgrFho47tyw9YFHQCFBf2qI9JYMQpycflg2KJAgMBAAECgYBltrwc1HzrykQFvDeXTLWwTv+TyFt19UkYhl6L5hNmTkRCI8RvzFUT5XK3ZLSmY2q7lazMTerbo44POU96XVvsV+ltmUW4ohh1cf+q7ICz73r+OEaFdxa+wHFthXvMuKpFbDiH89HfAmGGUVezf7dByClyVxn3yuKlb42ZC6AdsQJBAOyA+mBot7a98txTrMl4jRD1MI9t0dWHA51JzJ2vLBX4IlEr944Qhb6N0lNtYChEkEOCrTlLIDxWUtQhZbTP6R0CQQC/w8PcHulcbCY1JhBTefyzA4jmm9LZ0c+byqCSEiffE6/neTMLOxUpt9zDvtdWw7UvMZWgQ4a8QGZrlCw3Lw9dAkEAg9cqvE/kChU9q6FhszZmvUtR9MLttLD9TNN1I3ohg2W+C64M5L9FL4Lz+toAPrJqEZhpZIUCxWAB8ItlnTRB6QJBAKUMwsv3kxUoRG5kV5LxoK0XMsKBhaZSrmTBrxhqJgUbtb/+Eg/th1aD2LBl1oPoKE75V3Y8CICI0V5whunsSEUCQE1ZvMp5a0yblGENWU5F+kWT3aBCkmMN8Zqp2+R5p8kQ7Chxv7llCZ405YXnTdEQyLp+q6OW+eu0TdIQ3qHkA4c=";
    
    	/**
    	 * 公钥对象
    	 */
    	static PublicKey PUB_KEY;
    
    	/**
    	 * 私钥对象
    	 */
    	static PrivateKey PRI_KEY;
    
    	// 初始化
    	// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    	// 静态代码块,初始化密钥对象,供后面使用
    	static {
    		try {
    			PUB_KEY = restorePubKey();
    			PRI_KEY = restorePriKey();
    		} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
    			log.error("初始化出错", e);
    		}
    	}
    
    	/**
    	 * 从 .p12 文件中读取私钥。 <br>
    	 * <br>
    	 * 创建人: leigq <br>
    	 * 创建时间: 2017年10月28日 下午4:21:56 <br>
    	 *
    	 * @param pfxKeyFileName .p12文件路径
    	 * @param aliasName      私钥别名
    	 * @param pfxPassword    私钥密码
    	 * @return 私钥对象
    	 */
    	public static PrivateKey readP12Key(String pfxKeyFileName, String aliasName, String pfxPassword)
    			throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException {
    		InputStream fis = new FileInputStream(pfxKeyFileName);
    		KeyStore keyStore = KeyStore.getInstance("PKCS12");
    		keyStore.load(fis, pfxPassword.toCharArray());
    		return (PrivateKey) keyStore.getKey(aliasName, pfxPassword.toCharArray());
    	}
    
    	// 加密、解密
    	// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    
    	/**
    	 * 通用加密操作
    	 * <p>
    	 * 创建人:leigq <br>
    	 * 创建时间:2018年8月18日 下午5:37:32 <br>
    	 * <p>
    	 * 修改人: <br>
    	 * 修改时间: <br>
    	 * 修改备注: <br>
    	 * </p>
    	 *
    	 * @param key  公钥或密钥对象
    	 * @param data 明文字符串
    	 * @return 密文字节数组用Base64算法编码成的字符串,方便传输、储存
    	 */
    	public static String encrypt(Key key, String data)
    			throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
    			BadPaddingException {
    		Cipher cipher = Cipher.getInstance(CIPHER_MODE);
    		cipher.init(Cipher.ENCRYPT_MODE, key);
    		byte[] bytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
    		return BaseCoderUtils.encryptBase64(bytes);
    	}
    
    	/**
    	 * 通用解密操作
    	 * <p>
    	 * 创建人:leigq <br>
    	 * 创建时间:2018年8月18日 下午5:43:34 <br>
    	 * <p>
    	 * 修改人: <br>
    	 * 修改时间: <br>
    	 * 修改备注: <br>
    	 * </p>
    	 *
    	 * @param key  公钥或密钥对象
    	 * @param data 密文字符串(由密文字节数组用Base64算法编码成的字符串)
    	 * @return 明文字符串
    	 */
    	public static String decrypt(Key key, String data)
    			throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, UnsupportedEncodingException,
    			IllegalBlockSizeException, BadPaddingException {
    		Cipher cipher = Cipher.getInstance(CIPHER_MODE);
    		cipher.init(Cipher.DECRYPT_MODE, key);
    		byte[] bytes = cipher.doFinal(BaseCoderUtils.decryptBase64(data));
    		return new String(bytes, StandardCharsets.UTF_8);
    	}
    
    	/**
    	 * 用公钥加密 <br>
    	 * <br>
    	 * 创建人: leigq <br>
    	 * 创建时间: 2017年10月24日 下午2:00:49 <br>
    	 *
    	 * @param decoded 明文字符串
    	 * @return 密文字节数组用Base64算法编码成的字符串,方便传输、储存
    	 */
    	public static String encryptByPubKey(String decoded)
    			throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,
    			IllegalBlockSizeException, BadPaddingException {
    		return encrypt(PUB_KEY, decoded);
    	}
    
    	/**
    	 * 用私钥解密 <br>
    	 * <br>
    	 * 创建人: leigq <br>
    	 * 创建时间: 2017年10月24日 下午1:57:42 <br>
    	 *
    	 * @param encoded 密文字符串(由密文字节数组用Base64算法编码成的字符串)
    	 * @return 明文字符串
    	 */
    	public static String decryptByPriKey(String encoded) throws NoSuchPaddingException, BadPaddingException,
    			NoSuchAlgorithmException, IllegalBlockSizeException, UnsupportedEncodingException, InvalidKeyException {
    		return decrypt(PRI_KEY, encoded);
    	}
    
    	/**
    	 * 用私钥加密
    	 * <p>
    	 * 创建人:leigq <br>
    	 * 创建时间:2018年8月18日 下午5:37:32 <br>
    	 * <p>
    	 * 修改人: <br>
    	 * 修改时间: <br>
    	 * 修改备注: <br>
    	 * </p>
    	 *
    	 * @param decoded 明文字符串
    	 * @return 密文字节数组用Base64算法编码成的字符串,方便传输、储存
    	 */
    	public static String encryptByPriKey(String decoded)
    			throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
    			BadPaddingException {
    		return encrypt(PRI_KEY, decoded);
    	}
    
    	/**
    	 * 用公钥解密
    	 * <p>
    	 * 创建人:leigq <br>
    	 * 创建时间:2018年8月18日 下午5:43:34 <br>
    	 * <p>
    	 * 修改人: <br>
    	 * 修改时间: <br>
    	 * 修改备注: <br>
    	 * </p>
    	 *
    	 * @param encoded 密文字符串(由密文字节数组用Base64算法编码成的字符串)
    	 * @return 明文字符串
    	 */
    	public static String decryptByPubKey(String encoded)
    			throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, UnsupportedEncodingException,
    			IllegalBlockSizeException, BadPaddingException {
    		return decrypt(PUB_KEY, encoded);
    	}
    
    
    	/**
    	 * 还原公钥,X509EncodedKeySpec 用于构建公钥的规范
    	 * <p>
    	 * 创建人:leigq <br>
    	 * 创建时间:2018年8月18日 下午5:16:50 <br>
    	 * <p>
    	 * 修改人: <br>
    	 * 修改时间: <br>
    	 * 修改备注: <br>
    	 * </p>
    	 *
    	 * @return 公钥对象
    	 */
    	private static PublicKey restorePubKey()
    			throws NoSuchAlgorithmException, InvalidKeySpecException {
    		X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(BaseCoderUtils.decryptBase64(RSACoder.PUB_KEY_BASE64));
    		KeyFactory factory = KeyFactory.getInstance(ALGORITHM);
    		return factory.generatePublic(x509EncodedKeySpec);
    	}
    
    	/**
    	 * 还原私钥,PKCS8EncodedKeySpec 用于构建私钥的规范
    	 * <p>
    	 * 创建人:leigq <br>
    	 * 创建时间:2018年8月18日 下午5:19:09 <br>
    	 * <p>
    	 * 修改人: <br>
    	 * 修改时间: <br>
    	 * 修改备注: <br>
    	 * </p>
    	 *
    	 * @return 私钥对象
    	 */
    	private static PrivateKey restorePriKey()
    			throws NoSuchAlgorithmException, InvalidKeySpecException {
    		PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(BaseCoderUtils.decryptBase64(RSACoder.PRI_KEY_BASE64));
    		KeyFactory factory = KeyFactory.getInstance(ALGORITHM);
    		return factory.generatePrivate(pkcs8EncodedKeySpec);
    	}
    
    
    	// 更换密钥对
    	// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    
    	/**
    	 * 生成密钥对。注意这里是生成密钥对KeyPair,再由密钥对获取公私钥
    	 * <p>
    	 * 创建人:leigq <br>
    	 * 创建时间:2018年8月18日 下午7:35:21 <br>
    	 * <p>
    	 * 修改人: <br>
    	 * 修改时间: <br>
    	 * 修改备注: <br>
    	 * </p>
    	 */
    	public static void generateKeyPair() {
    		try {
    			KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
    			keyPairGenerator.initialize(KEY_SIZE);
    			KeyPair keyPair = keyPairGenerator.generateKeyPair();
    
    			/* 公钥、私钥用 encryptBase64 还是 encryptBase64Sun 加密都可以,后者的 Base64 是多行的,比较适合保存到文件的方式储存 */
    			RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
    			log.info("新公钥:{}", BaseCoderUtils.encryptBase64(publicKey.getEncoded()));
    
    			RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
    			log.info("新私钥:{}", BaseCoderUtils.encryptBase64(privateKey.getEncoded()));
    
    		} catch (NoSuchAlgorithmException e) {
    			log.error("生成密钥对异常:", e);
    		}
    	}
    }
    

    测试加密:

    /**
     * RSA 测试
     */
    @Slf4j
    class RSATest {
    	public static void main(String[] args) throws IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException,
    			NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
    		// 生成密钥对。注意这里是生成密钥对KeyPair,再由密钥对获取公私钥
    		RSACoder.generateKeyPair();
    
    		log.warn("公钥加密 >> 私钥解密");
    
    		String originalStr = "helloWorld";
    		log.warn("原文:{}", originalStr);
    
    		/* 公钥加密 >> 私钥解密  */
    		// 公钥加密
    		String encryptByPubKey = RSACoder.encryptByPubKey(originalStr);
    		log.warn("公钥加密后:" + encryptByPubKey);
    
    		// 私钥解密
    		String decryptByPriKey = RSACoder.decryptByPriKey(encryptByPubKey);
    		log.warn("私钥解密后:" + decryptByPriKey);
    
    
    		/* 私钥加密 >> 公钥解密 */
    		// 私钥加密
    		String encryptByPriKey = RSACoder.encryptByPriKey(originalStr);
    		log.warn("私钥加密后:" + encryptByPriKey);
    
    		// 公钥解密
    		String decryptByPubKey = RSACoder.decryptByPubKey(encryptByPriKey);
    		log.warn("公钥解密后:" + decryptByPubKey);
    	}
    }
    

    RSA加密、解密测试结果:

    20191026171006.png

    RSA 签名工具类:

    package com.blog.www.util.coder.asymmetrical;
    
    import com.blog.www.util.coder.base.BaseCoderUtils;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.codec.DecoderException;
    import org.apache.commons.codec.binary.Hex;
    
    import java.nio.charset.StandardCharsets;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.security.Signature;
    import java.security.SignatureException;
    
    /**
     * RSA签名验签类
     */
    @Slf4j
    public class RSASignature extends RSACoder {
    
    	/**
    	 * 用哪个算法来签名
    	 */
    	private static final String SIGNATURE_ALGORITHM = "SHA1WithRSA";
    
    
    	/* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 生成签名 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
    
    	/**
    	 * 用私钥生成 Base64数字签名
    	 * <br>
    	 *
    	 * @param encoded 加密字符串
    	 * @return 签名,已用Base64编码
    	 */
    	public static String signToBase64(String encoded) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
    		Signature sign = getSign(encoded.getBytes(StandardCharsets.UTF_8));
    		return BaseCoderUtils.encryptBase64(sign.sign());
    	}
    
    	/**
    	 * 用私钥生成16进制数字签名
    	 * <br>
    	 *
    	 * @param encoded 加密字符串
    	 * @return 签名,已用转16进制字符串
    	 */
    	public static String signToHex(String encoded) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
    		Signature sign = getSign(encoded.getBytes(StandardCharsets.UTF_8));
    		return Hex.encodeHexString(sign.sign());
    	}
    	/* ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 生成签名 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */
    
    
    
    	/* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 验证签名 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
    
    	/**
    	 * 用公钥校验 Base64数字签名
    	 * <br>
    	 *
    	 * @param encoded 加密数据
    	 * @param signed  签名,已用Base64编码
    	 * @return 校验成功返回true 失败返回false
    	 */
    	public static boolean verifyFromBase64(String encoded, String signed) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
    		Signature verify = getVerify(encoded.getBytes(StandardCharsets.UTF_8));
    		return verify.verify(BaseCoderUtils.decryptBase64(signed));
    	}
    
    	/**
    	 * 用公钥校验 16进制数字签名
    	 * <br>
    	 *
    	 * @param data   加密数据
    	 * @param signed 签名,是由字节数组转换成的16进制字符串
    	 */
    	public static boolean verifyFromHex(String data, String signed) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, DecoderException {
    		Signature verify = getVerify(data.getBytes(StandardCharsets.UTF_8));
    		return verify.verify(Hex.decodeHex(signed));
    	}
    	/* ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 验证签名 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */
    
    
    	/**
    	 * 用私钥生成数字签名对象
    	 * <br>
    	 *
    	 * @param encoded 加密字符串转换的字节数组
    	 * @return Signature,方便进一步转换为其他数据
    	 */
    	private static Signature getSign(byte[] encoded) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
    		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    		signature.initSign(PRI_KEY);
    		signature.update(encoded);
    		return signature;
    	}
    
    
    	/**
    	 * 用公钥生成校验数字签名对象
    	 * <br>
    	 *
    	 * @param data 加密字符串转换的字节数组
    	 * @return
    	 */
    	private static Signature getVerify(byte[] data) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
    		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    		signature.initVerify(PUB_KEY);
    		signature.update(data);
    		return signature;
    	}
    }
    
    

    测试签名:

    /**
     * RSA 签名测试
     */
    @Slf4j
    class RSASignTest {
    	public static void main(String[] args) throws NoSuchAlgorithmException,
    			InvalidKeyException, SignatureException, DecoderException {
    		// 上面公钥加密产生的密文
    		String ciphertext = "S1E4OieVAlGyrOB7CzKugseg/R9TGSdDhRSna64tTpxJubpndp2AwCrJ3myIoWEqXNBPKlPVo21vd+KQgzhQcX5WxoNXD5sLarmbZ5eFsBNQOuTzwIhSql+zaUKV6qq+RTSYNR4c/fqllh5Mviq73dB42bWbUY7nHlim+jGojPY=";
    
    		log.warn("私钥签名——公钥验证签名");
    
    		// 产生签名 16 进制签名
    		String signToBase64 = RSASignature.signToBase64(ciphertext);
    		log.warn("签名:[{}]", signToBase64);
    
    		// 验证签名
    		boolean verifyFromBase64 = RSASignature.verifyFromBase64(ciphertext, signToBase64);
    		log.warn("验证签名:[{}]", verifyFromBase64);
    
    
    		// 产生签名 16 进制签名
    		String signToHex = RSASignature.signToHex(ciphertext);
    		log.warn("签名:[{}]", signToHex);
    
    		// 验证签名
    		boolean verifyFromHex = RSASignature.verifyFromHex(ciphertext, signToHex);
    		log.warn("验证签名:[{}]", verifyFromHex);
    	}
    }
    

    测试结果:

    20191026171039.png

    2、DSA 签名

    DSA-Digital Signature Algorithm 是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。如果数据和签名不匹配则认为验证失败!数字签名的作用就是校验数据在传输过程中不被修改。数字签名,是单向加密的升级

    具体使用看:https://blog.csdn.net/jianggujin/article/details/53440060

    展开全文
  • 面试官:说一说你常用的加密算法有哪些
  • 五种对称加密算法总结

    千次阅读 2021-09-08 13:49:26
    对称加密算法的基石,具有学习价值 密钥长度56(JDK)、56/64(BC) 2、DESede(三重DES) 早于AES出现来替代DES 计算密钥时间太长、加密效率不高,所以也基本上不用 密钥长度112/168(JDK)、128/192(BC) 3、...
  • 对称加密算法对称加密算法的主要差别在于非对称加密算法用于加密和解密的密钥不相同,一个公开,称为公钥;一个保密,称为私钥。 RSA算法实现易于理解,对于RSA算法的测试只需要注意经公钥加密的数据是否可以...
  • 主要介绍了Java实现的对称加密算法AES,结合实例形式分析了对称加密算法AES的定义、特点、用法及使用场景,需要的朋友可以参考下
  • 加密算法
  • 三种非对称加密算法总结

    万次阅读 2018-09-06 10:45:14
    最经典的非对称加密算法 也可认为是使用最多的非对称加密算法 能用于密钥分配,也能用于加解密数据(“私钥加密,公钥解密”和“公钥加密,私钥解密”) 密钥长度:512~65536(64的整数倍) 只有发送方一个...
  • RSA非对称加密算法

    2019-02-14 23:12:03
    主要介绍RSA非对称加密算法的由来和应用场景,以及加密原理
  • 对称加密算法

    千次阅读 2022-04-28 17:53:16
    对称加密需要两把密钥:公钥和私钥,他们是一对,如果用公钥对数据加密,那么只能用对应的私钥解密。如果用私钥对数据加密,只能用对应的公钥进行解密。因为加密和解密用的是不同的密钥,所以称为非对称加密。 2....
  • 常见加密算法有哪些?是否对称

    千次阅读 2020-01-06 09:28:04
    常用的对称加密算法:DES、AES、3DES、RC2、RC4 常用的非对称加密算法:RSA、DSA、ECC 单向散列函数的加密算法:MD5、SHA 【Java面试题与答案】整理推荐 基础与语法 集合 网络编程 并发编程 Web 安全 ...
  • 1.对称加密算法加密和解密使用的密钥的是相同的,也就是只有一个密钥,而非对称加密算法有两个密钥,也就是加密和解密所使用的密钥是不同的 2.各自算法不同 3.对称加密算法加密速度快(相对的),非对称算法,密钥成...
  • 对称加密算法的加密密钥和解密密钥相同。或者虽然不同,但是可以通过其中一个密钥推导出另外一个密钥。 非对称加密算法的加密密钥和解密密钥不相同,并且从其中一个很难退出推导出另外一个。 对称加密优缺点: ...
  • 本文实例讲述了Python3对称加密算法AES、DES3。分享给大家供大家参考,具体如下: python3.6此库安装方式,需要pip3 install pycryptodome。 如site-packages中存在crypto、pycrypto,在pip之前,需要pip3 ...
  • 包括RSA算法的两种语言实现,原理正确,可以正常运行,对应博客为:https://blog.csdn.net/qq_41112170/article/details/104904340
  • 常用的三种非对称加密算法

    千次阅读 2020-08-29 11:45:37
    RSA(RSA algorithm):由RSA公司发明,是一个支持变长密钥的公开密钥算法,需要加密的文件块的长度也是可变的,非对称加密算法。 DSA(Digital Signature Algorithm):数字签名算法,是一种标准的DSS(数字签名...
  • 对称加密算法

    2022-03-13 16:19:59
    对称加密算法 所有的对称加密都一个共同的特点:加密和解密所用的密钥是相同的。  现代对称密码可以分为序列密码和分组密码两类:序列密码将明文中的每个字符单独加密后再组合成密文;而分组密码将原文分为...
  • AES对称加密算法的Python代码实现,含基础UI界面,课程设计 AES加密算法涉及4种操作,分别是字节替代、行移位、列混淆和轮密钥加,解密算法的每一步分别对应加密算法的逆操作,且所有操作的顺序相反。加解密中每轮的...
  • DES( Data Encryption Standard)算法,于1977年得到美国政府的正式许可,是一种用56位密钥来加密64位数据的方法。
  • 面试官:说一说你常用的加密算法有哪些加密算法通常被分为两种:对称加密算法和非对称加密算法。其中,对称加密算法在加密和解密时使用的密钥相同;非对称加密算法在加密和解密时使用的密钥不同,分为公钥和...
  • C语言实现AES-128对称加解密算法。编译环境:VS2010。请参考我的博客https://blog.csdn.net/u013073067/article/details/86529111 分析代码

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 95,987
精华内容 38,394
关键字:

对称密码算法有哪些