20.加密与算法

加密与算法

计算机加密技术就是为了实现上述目标,而现代计算机密码学理论是建立在严格的数学理论基础上的,密码学已经逐渐发展成一门科学。对于绝大多数开发者来说,设计一个安全的加密算法非常困难,验证一个加密算法是否安全更加困难,当前被认为安全的加密算法仅仅是迄今为止尚未被攻破。

  • 不要自己设计山寨的加密算法;
  • 不要自己实现已有的加密算法;
  • 不要自己修改已有的加密算法。

编码算法

URL编码和Base64编码都是编码算法,但不是加密算法

URL编码

URL编码是浏览器发送数据给服务器时使用的编码,它通常附加在URL的参数部分,目的是把任意文本数据编码为%前缀表示的文本,编码后的文本仅包含AZ,az,0~9,-,_,.,*和%,便于浏览器和服务器处理;
URL编码的规则:

  • 如果字符是AZ,az,0~9以及-、_、.、*,则保持不变;
  • 如果是其他字符,先转换为UTF-8编码,然后对每个字节以%XX表示。
    如果服务器收到URL编码的字符串,就可以对其进行解码,还原成原始字符串
    Java标准库提供了一个URLEncoder类来对任意字符串进行URL编码,URLDecoder可以解码
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class Main {
    public static void main(String[] args) {
        String encoded = URLEncoder.encode("中文!", StandardCharsets.UTF_8);
        System.out.println(encoded);
        String decoded = URLDecoder.decode("%E4%B8%AD%E6%96%87%21", StandardCharsets.UTF_8);
        System.out.println(decoded);
    }
}

Base64编码

Base64编码的目的是把二进制数据变成文本格式,这样在很多文本中就可以处理二进制数据。例如,电子邮件协议就是文本协议,如果要在电子邮件中添加一个二进制文件,就可以用Base64编码,然后以文本的形式传送。
Base64编码的缺点是传输效率会降低,因为它把原始数据的长度增加了1/3。
Base64编码可以把任意长度的二进制数据变为纯文本,且只包含AZ、az、0~9、+、/、=这些字符。它的原理是把3字节的二进制数据按6bit一组,用4个int整数表示,然后查表,把int整数用索引对应到字符,得到编码后的字符串。
因为6位整数的范围总是063,所以,能用64个字符表示:字符AZ对应索引025,字符az对应索引2651,字符09对应索引52~61,最后两个索引62、63分别用字符+和/表示。
Java标准库提供了Base64来对byte[]数组进行编解码和解码

import java.util.*;
public class Main {
    public static void main(String[] args) {
        byte[] input = new byte[] { (byte) 0xe4, (byte) 0xb8, (byte) 0xad };
        String b64encoded = Base64.getEncoder().encodeToString(input);
        System.out.println(b64encoded);
        byte[] output = Base64.getDecoder().decode("5Lit");
        System.out.println(Arrays.toString(output)); // [-28, -72, -83]
    }
}

哈希算法

哈希算法可用于验证数据完整性,具有防篡改检测的功能;哈希算法(Hash)又称摘要算法(Digest),对任意一组输入数据进行计算,得到一个固定长度的输出摘要,相同的输入一定得到相同的输出,不同的输入大概率得到不同的输出
Java字符串的hashCode()就是一个哈希算法,它的输入是任意字符串,输出是固定的4字节int整数。两个相同的字符串永远会计算出相同的hashCode,否则基于hashCode定位的HashMap就无法正常工作。

哈希碰撞

哈希碰撞是指两个不同的输入得到了相同的输出。哈希碰撞无法避免,安全的哈希算法可满足碰撞概率低和不能猜测输出。常用的哈希算法包括MD5和SHA-1,MD5因为输出长度较短,短时间内破解是可能的,目前已经不推荐使用

哈希算法用途

比对下载软件是否原版、存储用户口令。
用户口令上需要防范彩虹表(常用口令和哈希码的对应表)攻击,可以采取对每个口令额外添加随机数,称之为加盐(salt):

BouncyCastle

BouncyCastle是一个提供了很多哈希算法和加密算法的第三方库,它提供了Java标准库没有的一些算法,如RipeMD160哈希算法
使用BouncyCastle第三方提供的算法:
首先把BouncyCastle提供的jar包bcprov-jdk15on-xxx.jar放到classpath中,此jar包可以从官方网站下载。
Java标准库的java.security包提供了一种标准机制,允许第三方提供商无缝接入。要使用BouncyCastle提供的RipeMD160算法,需要先把BouncyCastle注册一下,后续就可以使用BouncyCastle提供的所有哈希算法和加密算法

public class Main {
    public static void main(String[] args) throws Exception {
        // 注册BouncyCastle:
        Security.addProvider(new BouncyCastleProvider());
        // 按名称正常调用:
        MessageDigest md = MessageDigest.getInstance("RipeMD160");
        md.update("HelloWorld".getBytes("UTF-8"));
        byte[] result = md.digest();
        System.out.println(new BigInteger(1, result).toString(16));
    }
}

Hmac算法

Hmac算法是一种基于密钥的消息认证码算法,全称是Hash-based Message Authentication Code,是一种更安全的消息摘要算法。
Hmac算法总是和某种哈希算法配合起来用。例如,我们使用MD5算法,对应的就是HmacMD5算法,它相当于“加盐”的MD5。
Hmac本质上就是把key混入摘要的算法。验证此哈希时,除了原始的输入数据,还要提供key
和MD5相比,使用HmacMD5的步骤是:

  • 通过名称HmacMD5获取KeyGenerator实例;
  • 通过KeyGenerator创建一个SecretKey实例;
  • 通过名称HmacMD5获取Mac实例;
  • 用SecretKey初始化Mac实例;
  • 对Mac实例反复调用update(byte[])输入数据;
  • 调用Mac实例的doFinal()获取最终的哈希值。

对称加密算法

对称加密算法就是传统的用一个密码进行加密和解密。
从程序的角度看,所谓加密,就是这样一个函数,它接收密码和明文,然后输出密文:secret = encrypt(key, message);
而解密则相反,它接收密码和密文,然后输出明文:plain = decrypt(key, secret);
在软件开发中,常用的对称加密算法有:DES,AES,IDEA
密钥长度由算法设计决定,AES的密钥长度是128/192/256位;
Java使用对称加密算法需要指定算法名称、工作模式和填充模式

PBE Password Based Encryption

PBE算法通过用户口令和安全的随机salt计算出Key,然后再进行加密;
Key通过口令和安全的随机salt计算得出,大大提高了安全性;
PBE算法内部使用的仍然是标准对称加密算法(例如AES)

密钥交换算法DH

DH算法(Diffie-Hellman算法)是一种密钥交换协议,通信双方通过不安全的信道协商密钥,然后进行对称加密传输。
DH算法没有解决中间人攻击。

非对称加密算法

非对称加密就是加密和解密使用的不是相同的密钥,只有同一个公钥-私钥对才能正常加解密;
只使用非对称加密算法不能防止中间人攻击。

签名算法

数字签名就是用发送方的私钥对原始数据进行签名,只有用发送方公钥才能通过签名验证。
数字签名用于:防止伪造、防止抵赖、检测篡改。
常用的数字签名算法包括:MD5withRSA/SHA1withRSA/SHA256withRSA/SHA1withDSA/SHA256withDSA/SHA512withDSA/ECDSA等。

数字证书

数字证书是集合了多种密码学算法,用于实现数据加解密、身份认证、签名等多种功能的一种安全标准。
数字证书可以防止中间人攻击,因为它采用链式签名认证,即通过根证书(Root CA)去签名下一级证书,层层签名直到最终的用户证书。而Root CA证书内置于操作系统中,所以,任何经过CA认证的数字证书都可以对其本身进行校验,确保证书本身不是伪造的。
数字证书存储的是公钥,可以安全公开,而私钥必须严格保密。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值