Java实现加密算法(一、单项加密)

本文介绍了哈希算法的基本概念和重要性,如MD5、SHA家族和HMAC等单向加密算法。通过Java代码示例展示了如何使用这些算法进行数据加密,强调了它们在数据完整性验证和防止篡改中的应用。此外,还提及了RipeMD-160算法的使用,以及对BouncyCastleProvider的注册以支持该算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

本文主要对单向加密算法做个概况性的介绍,然后给出简单的加密算法 Java 实现(即MD5、SHA系列、Hmac)。


一、介绍

哈希算法(Hash)又称摘要算法(Digest),它的作用是:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。
哈希算法最重要的特点就是:

  • 相同的输入一定得到相同的输出;
  • 不同的输入大概率得到不同的输出。

所以,哈希算法的目的:为了验证原始数据是否被篡改。

Java字符串的hashCode()就是一个哈希算法,它的输入是任意字符串,输出是固定的4字节int整数。

哈希碰撞是指:两个不同的输入得到了相同的输出。

因为输出的字节长度是固定的,String的hashCode()输出是4字节整数,最多只有4294967296种输出,但输入的数据长度是不固定的,有无数种输入。所以,哈希算法是把一个无限的输入集合映射到一个有限的输出集合,必然会产生碰撞。

哈希算法,根据碰撞概率,哈希算法的输出长度越长,就越难产生碰撞,也就越安全。

常用的哈希算法有:

算法

输出长度(位)

输出长度(字节)

MD5

128 bits

16 bytes

SHA-1

160 bits

20 bytes

RipeMD-160

160 bits

20 bytes

SHA-256

256 bits

32 bytes

SHA-512

512 bits

64 bytes

单向加密的常用算法

1. MD5

Message Digest algorithm 5,信息摘要算法,MD5

  • 一般用于确保信息的传输完整一致性,校验传输的数据是否被修改,一旦原始信息被修改,生成的 MD5 值将会变得很不同
  • 算法能将任意大小、格式的文字或文件进行加密从而产生 128 bit(16 字节)的散列值。如同人的指纹,不同文本的 MD5 值是不同的。
  • 极端情况:就是不同的字符串的 MD5 值一样,这叫哈希碰撞。2009 年中科院就已经实现了相应的碰撞算法,不过 MD5 应用仍然很广泛
  • 一般不可破解,除非使用穷举法,难度依旧很大

2.SHA 家族

  • 是一个密码散列函数家族,是 FIPS 所认证的安全散列算法
  • 和 MD5 类似,都是对文本进行散列,产生一定长度的散列值

3. HMAC

Hash Message Authentication Code,散列消息鉴别码

  • 是一种通过特别计算方式之后产生的消息认证码(MAC),使用密码散列函数,同时结合一个加密密钥。它可以用来保证数据的完整性,同时可以用来作某个消息的身份验证。

二、使用步骤

1.MD5

	public static void main(String[] args) throws NoSuchAlgorithmException {
		//  即将加密数据
		String data = "即将加密的数据";
		//	创建基于MD5算法的消息摘要对象
		MessageDigest md5 = MessageDigest.getInstance("MD5");
		
		md5.update(data.getBytes());//    向对象中添加数据
		
		byte[] digestByte =  md5.digest();//    对数据加密,并获得加密后的字节数组
		System.out.println(Arrays.toString(digestByte));
		BigInteger digestBig = new BigInteger(1,digestByte);//将加密数据转换为正的16进制字符串
		System.out.println(digestBig.toString(16));//按照16进制输出
		
	}

 2.SHA 家族

    public static void main(String[] args) throws Exception {
        String data = "即将加密的数据";
		// 拿到一个SHA转换器
		MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
		sha1.update(data.getBytes());
//      byte[] digestByte =  sha1.digest();//    对数据加密,并获得加密后的字节数组
//      System.out.println(Arrays.toString(digestByte));
		BigInteger encData = new BigInteger(1,sha1.digest());
		System.out.println(encData);
		//加密之后转换为32进制字符串
		System.out.println("encData = "+ encData.toString(32));
    }

3. HMAC

首次创建,利用KeyGenerator创建密钥

	/**
     * MAC算法可选以下多种算法
     * <pre>
     * HmacMD5
     * HmacSHA1
     * HmacSHA256
     * HmacSHA384
     * HmacSHA512
     * </pre>
     */
    public static final String KEY_MAC = "HmacMD5";
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException {
	    
		String data = "即将加密的数据";
//		String key = "给定的密钥";
		
        //	产生密钥
		//	获取HmacMD5密钥生成器
		KeyGenerator keyGen = KeyGenerator.getInstance(KEY_MAC);
		
        //	生成密钥
		SecretKey secretKey = keyGen.generateKey();
		System.out.println(Arrays.toString(keyGen.generateKey().getEncoded()));
		//	生成密钥字节数组:[-104, 24, 115, -66, 28, 2, -36, -13, 44, 34, 50, -31, -66, -26, -98, 118, 94, -83, 31, -124, 59, -57, 46, 31, -122, 80, 90, 127, -127, 119, -16, 48, -13, -70, -53, -24, 20, -111, 44, -42, 122, 45, 44, -26, -3, -127, 95, 119, -38, -40, 57, -70, -13, 38, 93, 86, -102, -83, 124, 63, 70, -117, 54, 60]
		
		Mac mac = Mac.getInstance(KEY_MAC);
		
		mac.init(secretKey);//	初始化密钥
		mac.update(data.getBytes());
		
		byte[] bytes = mac.doFinal();//	加密处理,并获取加密结果
		
		BigInteger bigestencode = new BigInteger(1,bytes);
		
		System.out.println(bigestencode.toString(16));
		//	结果:7e78dd332d999e8a4345af95aea506af
	}

后续密码对比

	/**
     * MAC算法可选以下多种算法
     * <pre>
     * HmacMD5
     * HmacSHA1
     * HmacSHA256
     * HmacSHA384
     * HmacSHA512
     * </pre>
     */
    public static final String KEY_MAC = "HmacMD5";
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException {
	    
		String data = "即将加密的数据";
        //  1.给定密钥的字节数组
        byte[] keys = new byte[]{-104, 24, 115, -66, 28, 2, -36, -13, 44, 34, 50, -31, -66, -26, -98, 118, 94, -83, 31, -124, 59, -57, 46, 31, -122, 80, 90, 127, -127, 119, -16, 48, -13, -70, -53, -24, 20, -111, 44, -42, 122, 45, 44, -26, -3, -127, 95, 119, -38, -40, 57, -70, -13, 38, 93, 86, -102, -83, 124, 63, 70, -117, 54, 60};
		//  2.给定密钥
        String key = "给定的密钥";
		
//      //	产生密钥
//      //	获取HmacMD5密钥生成器
//		KeyGenerator keyGen = KeyGenerator.getInstance(KEY_MAC);
		
//      //	生成密钥
//		SecretKey secretKey = keyGen.generateKey();
        //	生成密钥
        //  1.根据给定的密钥字节数组,第二参数指定一个密钥算法的名称
        SecretKey secretKey1 = new SecretKeySpec(keys, KEY_MAC);
		//  2.根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
		SecretKey secretKey2 = new SecretKeySpec(key.getBytes(), KEY_MAC);
		Mac mac = Mac.getInstance(KEY_MAC);
		
		mac.init(secretKey1);//	初始化密钥
		mac.update(data.getBytes());
		
		byte[] bytes = mac.doFinal();//	加密处理,并获取加密结果
		
		BigInteger bigestencode = new BigInteger(1,bytes);
		
		System.out.println(bigestencode.toString(16));
		//	结果:7e78dd332d999e8a4345af95aea506af
	}

4.RipeMD-160

public static void main(String[] args) throws NoSuchAlgorithmException {
		
		//	注册BouncyCastleBouncycastleProvider通知类
		//	将提供的消息摘要算法注册至Security
		Security.addProvider(new BouncyCastleProvider());
		
		//	获取RipeMD160算法的"消息摘要对象"(加密对象)
		MessageDigest ripeMd160 = MessageDigest.getInstance("RipeMD160");
		
		//	更新原始数据
		ripeMd160.update( "wbjxxmy".getBytes());
		
		//	获取消息摘要(加密)
		byte[] result = ripeMd160.digest( );
		
		//	消息摘要的字节长度和内容
		System.out.println("加密结果(字节长度):"+result.length);// 160位=20字节
		System.out.println("加密结果(字节内容):"+Arrays.toString(result));
		//	16进制内容字符串
		String hex = new BigInteger(1,result).toString(16);
		System.out.println("加密结果(字符串长度);"+hex.length()); //20字节=40个字符
		System.out.println("加密结果(字符串内容):" +hex);
	}


总结

        常用的单向加密算法介绍和简单应用就是这些,MD5和SHA系列比较简单,就算大量数据泄露也不会有影响,但是为了防止彩虹表攻击,所以有了Hmac的出现。

        RipeMD-160,Java中并不能直接调用,所以需要导入Jar包,最后写RipeMD-160的原因是为了注册BouncyCastleBouncycastleProvider通知类,将提供的消息摘要算法注册至Security,以防止有其他的注册行为,而导致加密算法无法使用。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bitw-QwQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值