Java Language——数据加密算法与编码方式

数据加密是计算机系统对信息进行保护的一种最可靠的办法。它利用密码技术对信息进行加密,实现信息隐蔽,从而起到保护信息的安全的作用。本文主要介绍了几种常见的数据加密算法(对称密码算法/非对称密码算法)的 Java 实现和常见编码方式的使用。

1.对称加密算法

对称加密指加密和解密使用相同密钥的加密算法。常见的对称加密算法包括:

算法 说明 密钥长度 默认密钥长度 工作模式 填充方式 默认填充方式 实现方式
DES 数据加密标准 56bit 56bit ECB、CBC、PCBC、CTR、CTS、CFB、CFB8-CFB128、OFB、OFB8-OFB128 NoPadding、PKCS5Padding、ISO10126Padding PKCS5Padding JDK
3DES 进行了三重DES加密的算法 112bit、168bit 168bit ECB、CBC、PCBC、CTR、CTS、CFB、CFB8-CFB128、OFB、OFB8-OFB128 NoPadding、PKCS5Padding、ISO10126Padding PKCS5Padding JDK
AES(推荐使用) 高级数据加密标准,AES算法可以有效抵制针对DES的攻击算法 128bit、192bit、256bit 128bit ECB、CBC、PCBC、CTR、CTS、CFB、CFB8-CFB128、OFB、OFB8-OFB128 NoPadding、PKCS5Padding、ISO10126Padding PKCS5Padding JDK

1.AES算法

Java实现,密钥建立时间短、灵敏性好、内存需求低、安全性高。AES 算法我们选择 CBC 模式,可以增强安全性。

1、生成密钥

KeyGenerator keyGen = KeyGenerator.getInstance("AES");       // 密钥生成器
keygen.init(128);                                            // 默认128, 获得无政策权限后可为192或256
SecretKey secretKey = keyGen.generateKey();                  // 生成密钥
byte[] enCodeFormat = secretKey.getEncoded();                // 密钥字节数组

2、定义16 byte IV

private static final byte[] IV_BYTES = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};

3、AES-CBC 加密

IvParameterSpec iv = new IvParameterSpec(IV_BYTES);
SecretKeySpec sKeySpec = new SecretKeySpec(key, "AES");      // key: 密钥
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");  // 密码器
cipher.init(Cipher.ENCRYPT_MODE, sKeySpec, iv);              // 对Cipher初始化, 加密模式
byte[] result = cipher.doFinal(value.getBytes("UTF-8"));     // value: 需要加密的字符串, result: 加密后的结果

4、AES-CBC 解密

IvParameterSpec iv = new IvParameterSpec(IV_BYTES);
SecretKeySpec sKeySpec = new SecretKeySpec(key, "AES");      // key: 密钥
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");  // 密码器
cipher.init(Cipher.DECRYPT_MODE, sKeySpec, iv);              // 对Cipher初始化, 解密模式
String result = new String(cipher.doFinal(value), "UTF-8");  // value: 需要解密的二进制字节数组, result: 解密后的结果

2.非对称加密算法

非对称加密算法是一种基于密钥的保密方法,需要公开密钥和私有密钥,在文件加密、尤其是网银中应用广泛。非对称密码算法比对称密码算法更安全。常见的非对称加密算法包括:

算法 说明 密钥长度 默认密钥长度 工作模式 填充方式 实现方式
DH 密钥交换算法 512-1024 (64的整数倍) 1024 JDK
RSA(推荐使用) 基于因子分解,用于数据加密和数字签名 512-65536 (64的整数倍) 1024 ECB NoPadding、PKCS1Padding、OAEPWITHMD5AndMGF1Padding、OAEPWITHSHA1AndMGF1Padding、OAEPWITHSHA256AndMGF1Padding、OAEPWITHSHA384AndMGF1Padding、OAEPWITHSHA512AndMGF1Padding JDK
2048 NONE NoPadding、PKCS1Padding、OAEPWITHMD5AndMGF1Padding、OAEPWITHSHA1AndMGF1Padding、OAEPWITHSHA224AndMGF1Padding、OAEPWITHSHA256AndMGF1Padding、OAEPWITHSHA384AndMGF1Padding、OAEPWITHSHA512AndMGF1Padding、ISO9796-1Padding BC
ElGamal 基于离散对数,只提供了公钥加密算法,私钥不能加密 160-16384 (8的整数倍) 1024 ECB、NONE “和如上RSA的BC实现相同” BC
ECC 椭圆曲线加密

1.RSA算法

初始化密钥:

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); // 密钥生成器
keyPairGenerator.initialize(1024);                                       // 默认1024
KeyPair keyPair = keyPairGenerator.generateKeyPair();                    // 生成密钥
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();          // 获取公钥
RSAPrivateKey rsaPrivateKey =  (RSAPrivateKey) keyPair.getPrivate();     // 获取私钥

公钥需要发送给客户端,私钥存储在服务端中。

1、私钥加密,公钥解密

服务端私钥加密:

PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded()); // rsaPrivateKey:私钥
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");                   // 密码器
cipher.init(Cipher.ENCRYPT_MODE, privateKey);                // 对Cipher初始化, 加密模式
byte[] result = cipher.doFinal(inStr.getBytes("UTF-8"));     // inStr: 需要加密的字符串, result: 加密后的结果

客户端公钥解密:

X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded()); // rsaPublicKey:公钥
keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");                   // 密码器
cipher.init(Cipher.DECRYPT_MODE, publicKey);                 // 对Cipher初始化, 解密模式
String result = new String(cipher.doFinal(inByte), "UTF-8"); // inByte: 需要解密的二进制字节数组, result:解密后的结果

2、公钥加密,私钥解密

客户端公钥加密:

X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded()); //rsaPublicKey:公钥
keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");                   // 密码器
cipher.init(Cipher.ENCRYPT_MODE, publicKey);                 // 对Cipher初始化, 加密模式
byte[] result = cipher.doFinal(inStr.getBytes("UTF-8"));     // inStr: 需要加密的字符串, result: 加密后的结果

服务端私钥解密:

PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded()); // rsaPrivateKey: 私钥
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");                   // 密码器
cipher.init(Cipher.DECRYPT_MODE, privateKey);                // 对Cipher初始化, 解密模式
String result = new String(cipher.doFinal(inByte), "UTF-8"); // inByte: 需要解密的二进制字节数组, result: 解密后的结果

3.编码方式

1.Base64编码

Base64 是网络上最常见的用于传输 8 位字节码的编码方式之一。Base64 不是加密算法,而是一种编码方式,由于加密后都是 byte[],为了可读性,一般将 byte[] 转为 base64 编码。最简单的使用方法是添加如下 Maven 依赖:

<dependency>
    <groupId>commons-codecgroupId>
    <artifactId>commons-codecartifactId>
    <version>1.11version>
dependency>

commons-codec 是 Apache 开源组织提供的用于摘要运算、编码的包 (简化 JDK)。Base64 编码和解码的方法如下:

// 编码,inStr:需要编码的字符串
String result = new String(Base64.encodeBase64(inStr.getBytes()), "UTF-8");
// 解码,inStr:需要解码的字符串
String result = new String(Base64.decodeBase64(inStr.getBytes()), "UTF-8");

自定义 Base64 编码:

2.URL编码

URL编码 (URL encoding),也称作百分号编码 (Percent-encoding), 是特定上下文的统一资源定位符 (URL) 的编码机制。适用于统一资源标识符 (URI) 的编码,也用于为 “application/x-www-form-urlencoded” MIME 准备数据, 因为它用于通过 HTTP 的请求操作 (request) 提交 HTML 表单数据。

URL 编码和解码的方法如下:

// 编码, inStr: 需要编码的字符串
String result = URLEncoder.encode(inStr, "UTF-8");
// 解码, inStr: 需要解码的字符串
String result = URLDecoder.decode(inStr, "UTF-8");

4.消息摘要算法

消息摘要算法是为了验证数据的完整性而出现的,它是数字签名的核心算法。常见的消息摘要算法包括:

算法 说明 摘要长度 包含算法 实现方式 适用场景
MD 消息摘要,不可逆加密 128 MD2、MD4、MD5 JDK(MD2、MD5)、BC(MD4) 用户注册的时候对密码进行加密
SHA 安全散列算法,固定长度摘要信息,不可逆加密 SHA-1(160)、SHA-224(224)、SHA-256(256)、SHA-384(384)、SHA-512(512) SHA-1、SHA-2(SHA-224、SHA-256、SHA-384、SHA-512) JDK(SHA-1、SHA-256、SHA-384、SHA-512)、BC(SHA-224)
MAC 消息认证码,不可逆加密 JDK

消息摘要算法加密最简单的方法是使用 commons-codec:

// MD5
String md5Str = DigestUtils.md5Hex(inStr); //inStr: 需要加密的字符串, md5Str: 加密后的结果

// SHA1
String sha1Str = DigestUtils.sha1Hex(inStr)); //inStr: 需要加密的字符串, sha1Str: 加密后的结果

你可能感兴趣的:(Java)