25、Java安全编程:证书读取、加密及算法标准详解

Java安全编程:证书读取、加密及算法标准详解

1. 读取包含证书的文件

在处理包含证书的文件时,我们常常会遇到Base64编码的证书,这些证书以 -----BEGIN CERTIFICATE----- 开头,以 -----END CERTIFICATE----- 结尾。下面为你介绍两种读取此类文件的方法。

1.1 逐个读取证书

此方法将 FileInputStream 转换为 ByteArrayInputStream ,这样每次调用 generateCertificate 时,输入流的读取位置都能正确定位。具体代码如下:

FileInputStream fis = new FileInputStream(filename);
DataInputStream dis = new DataInputStream(fis);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
byte[] bytes = new byte[dis.available()];
dis.readFully(bytes);
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
while (bais.available() > 0) {
    Certificate cert = cf.generateCertificate(bais);
    System.out.println(cert.toString());
}

1.2 解析PKCS #7格式的证书回复

当需要从PKCS #7格式的文件中提取所有证书时,可以使用以下代码:

FileInputStream fis = new FileInputStream(filename);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Collection c = cf.generateCertificates(fis);
Iterator i = c.iterator();
while (i.hasNext()) {
    Certificate cert = (Certificate) i.next();
    System.out.println(cert.toString());
}

1.3 流程图

graph TD
    A[开始] --> B[打开文件输入流]
    B --> C{选择读取方式}
    C -->|逐个读取| D[转换为字节数组输入流]
    C -->|解析PKCS #7| E[生成证书集合]
    D --> F[逐个生成证书并输出]
    E --> G[遍历集合输出证书]
    F --> H[结束]
    G --> H

2. 使用加密技术

2.1 生成密钥

以DES加密算法为例,使用 KeyGenerator 生成密钥:

KeyGenerator keygen = KeyGenerator.getInstance("DES");
SecretKey desKey = keygen.generateKey();

2.2 创建并初始化密码器

创建一个DES密码器,采用电子密码本(ECB)模式和PKCS #5填充方式:

Cipher desCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
desCipher.init(Cipher.ENCRYPT_MODE, desKey);

2.3 加密和解密操作

byte[] cleartext = "This is just an example".getBytes();
byte[] ciphertext = desCipher.doFinal(cleartext);
desCipher.init(Cipher.DECRYPT_MODE, desKey);
byte[] cleartext1 = desCipher.doFinal(ciphertext);

2.4 操作步骤总结

  1. 生成密钥:使用 KeyGenerator 实例化并生成密钥。
  2. 创建密码器:指定算法、模式和填充方式。
  3. 初始化密码器:选择加密或解密模式。
  4. 执行加密或解密操作:调用 doFinal 方法。

3. 使用基于密码的加密

3.1 收集用户密码

由于 String 对象不可变,不适合存储敏感信息,因此使用 char 数组收集用户密码:

public char[] readPasswd(InputStream in) throws IOException {
    char[] buf;
    int i;
    buf = lineBuffer = new char[128];
    int room = buf.length;
    int offset = 0;
    int c;
    while (true) {
        switch (c = in.read()) {
            case -1:
            case '\n':
                break loop;
            int c2 = in.read();
            if ((c2 != '\n') && (c2 != -1)) {
                if (!(in instanceof PushbackInputStream)) {
                    in = new PushbackInputStream(in);
                }
                ((PushbackInputStream)in).unread(c2);
            } else {
                break loop;
            }
            default:
                if (--room < 0) {
                    buf = new char[offset + 128];
                    room = buf.length - offset - 1;
                    System.arraycopy(lineBuffer, 0, buf, 0, offset);
                    Arrays.fill(lineBuffer, ' ');
                    lineBuffer = buf;
                }
                buf[offset++] = (char) c;
                break;
        }
        if (offset == 0) {
            return null;
        }
        char[] ret = new char[offset];
        System.arraycopy(buf, 0, ret, 0, offset);
        return ret;
    }
}

3.2 生成PBE密钥和参数

PBEKeySpec pbeKeySpec;
PBEParameterSpec pbeParamSpec;
SecretKeyFactory keyFac;
byte[] salt = { (byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c, (byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99 };
int count = 20;
pbeParamSpec = new PBEParameterSpec(salt, count);
System.out.print("Enter encryption password:  ");
System.out.flush();
pbeKeySpec = new PBEKeySpec(readPasswd(System.in));
keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);

3.3 创建并初始化PBE密码器

Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);

3.4 加密操作

byte[] cleartext = "This is another example".getBytes();
byte[] ciphertext = pbeCipher.doFinal(cleartext);

3.5 操作步骤总结

  1. 收集用户密码:使用 readPasswd 方法。
  2. 生成盐和迭代次数:用于PBE加密。
  3. 创建PBE密钥规范和参数规范。
  4. 生成PBE密钥:使用 SecretKeyFactory
  5. 创建并初始化PBE密码器。
  6. 执行加密操作。

4. 标准名称

4.1 消息摘要算法

算法名称 描述
MD2 定义于RFC 1319,输出128位摘要
MD5 定义于RFC 1321,输出128位摘要
SHA-1 定义于NIST FIPS 180 - 2,160位哈希函数
SHA-256 256位哈希函数,提供128位安全
SHA-384 可通过截断SHA - 512获得
SHA-512 512位哈希函数,提供256位安全

4.2 密钥和参数算法

算法名称 描述
DSA 数字签名算法,定义于FIPS PUB 186
RSA 加密算法,定义于PKCS #1
Diffie-Hellman 密钥交换算法,定义于PKCS #3
Blowfish Bruce Schneier设计的块密码
DES 数据加密标准,定义于FIPS PUB 46 - 2
DESede 三重DES加密
PBE 基于密码的加密算法(PKCS #5)

4.3 数字签名算法

算法名称 描述
SHA1withDSA 使用SHA - 1摘要和DSA创建并验证签名
MD2withRSA 使用MD2摘要和RSA创建并验证签名
MD5withRSA 使用MD5摘要和RSA创建并验证签名
SHA1withRSA 使用SHA - 1和RSA的签名算法
with 用于形成特定摘要和加密算法的签名算法名称

4.4 随机数生成算法

算法名称 描述
SHA1PRNG SUN提供的伪随机数生成算法,基于SHA - 1

4.5 证书类型

证书类型 描述
X.509 定义于X.509

4.6 密钥库类型

密钥库类型 描述
JKS SUN提供的密钥库实现
PKCS12 个人身份信息传输语法,定义于PKCS #12
JCEKS SunJCE提供的密钥库实现

4.7 服务属性

属性名称 描述
KeySize 提供者支持的最大密钥大小
ImplmentedIn 实现方式:软件或硬件

4.8 密码器算法、模式和填充

4.8.1 算法
算法名称 描述
AES 高级加密标准,支持128、192和256位密钥
Blowfish Bruce Schneier设计的块密码
DES 数据加密标准
DESede 三重DES加密
PBEWith And 基于密码的加密算法
RC2, RC4, RC5 Ron Rivest开发的可变密钥大小加密算法
RSA 加密算法,定义于PKCS #1
4.8.2 模式
模式名称 描述
NONE 无模式
CBC 密码块链接模式,定义于FIPS PUB 81
CFB 密码反馈模式,定义于FIPS PUB 81
ECB 电子密码本模式,定义于NIST FIPS PUB 81
OFB 输出反馈模式,定义于FIPS PUB 81
PCBC 传播密码块链接模式,由Kerberos V4定义
4.8.3 填充
填充名称 描述
NoPadding 无填充
OAEPWith And Padding 最优非对称加密填充,如OAEPWithMD5AndMGF1Padding
PKCS5Padding 定义于RSA Laboratories的PKCS #5
SSL3Padding 定义于SSL协议版本3.0

4.9 密钥生成算法

算法名称 描述
AES 高级加密标准
Blowfish 块密码
DES 数据加密标准
DESede 三重DES加密
HmacMD5 HMAC - MD5密钥哈希算法
HmacSHA1 HMAC - SHA1密钥哈希算法

4.10 秘密密钥算法

算法名称 描述
AES 高级加密标准
DES 数据加密标准
DESede 三重DES加密
PBEWith And 基于密码的加密算法

4.11 MAC算法

算法名称 描述
HmacMD5 定义于RFC 2104的HMAC - MD5密钥哈希算法
HmacSHA1 定义于RFC 2104的HMAC - SHA1密钥哈希算法
PBEWith 用于PKCS #5 v2.0基于密码的消息认证

5. 算法规范

5.1 SHA - 1消息摘要算法

  • 名称 :SHA - 1
  • 类型 :MessageDigest
  • 描述 :定义于NIST的FIPS 180 - 1,输出160位摘要

5.2 MD2消息摘要算法

  • 名称 :MD2
  • 类型 :MessageDigest
  • 描述 :定义于RFC 1319,输出128位摘要

5.3 MD5消息摘要算法

  • 名称 :MD5
  • 类型 :MessageDigest
  • 描述 :定义于RFC 1321,输出128位摘要

5.4 数字签名算法(SHA1withDSA)

  • 名称 :SHA1withDSA
  • 类型 :Signature
  • 描述 :使用DSA和SHA - 1消息摘要算法,定义于NIST FIPS 186
  • 密钥对算法 :DSA

6. 算法规范的重要性及应用场景

6.1 算法规范的重要性

在实现加密算法时,遵循标准的算法规范至关重要。这些规范确保了不同实现之间的互操作性和安全性。例如,当使用特定的数字签名算法时,遵循标准规范可以保证签名的生成和验证过程在不同系统中能够正确执行。如果不遵循规范,可能会导致签名验证失败,从而影响系统的安全性和可靠性。

6.2 应用场景分析

不同的算法适用于不同的应用场景,下面通过表格展示部分算法的应用场景:
| 算法类型 | 算法名称 | 应用场景 |
| ---- | ---- | ---- |
| 消息摘要算法 | SHA - 1 | 用于文件完整性验证、数字签名中的摘要生成等,但由于其安全性逐渐降低,在一些对安全性要求较高的场景中逐渐被替代 |
| 消息摘要算法 | MD5 | 早期常用于文件校验,但由于存在碰撞漏洞,不适合用于安全敏感的场景 |
| 密钥和参数算法 | RSA | 广泛用于安全通信、数字签名、密钥交换等场景,如HTTPS协议中的密钥交换 |
| 数字签名算法 | SHA1withDSA | 在需要进行数字签名的场景中使用,如电子文档的签名、软件的数字签名等 |
| 随机数生成算法 | SHA1PRNG | 用于生成随机数,如在加密密钥生成过程中作为随机数源 |

6.3 流程图:算法选择流程

graph TD
    A[开始] --> B{应用场景需求}
    B -->|文件完整性验证| C(SHA - 1、MD5等消息摘要算法)
    B -->|安全通信、密钥交换| D(RSA、Diffie - Hellman等密钥和参数算法)
    B -->|数字签名| E(SHA1withDSA、MD5withRSA等数字签名算法)
    B -->|随机数生成| F(SHA1PRNG等随机数生成算法)
    C --> G[选择合适算法]
    D --> G
    E --> G
    F --> G
    G --> H[结束]

7. 总结与实践建议

7.1 总结

本文详细介绍了Java安全编程中的多个重要方面,包括读取包含证书的文件、使用加密技术、基于密码的加密、标准名称和算法规范等内容。通过具体的代码示例和操作步骤,展示了如何在Java中实现这些安全功能。同时,对各种算法的标准名称和规范进行了梳理,为开发者在选择和使用算法时提供了参考。

7.2 实践建议

  • 证书读取 :在读取包含证书的文件时,根据文件的格式选择合适的读取方法。如果是Base64编码的单个证书文件,可以使用逐个读取的方法;如果是PKCS #7格式的证书回复文件,则使用解析PKCS #7的方法。
  • 加密技术 :在使用加密技术时,要根据实际需求选择合适的加密算法、模式和填充方式。例如,对于对称加密,可以选择DES、AES等算法;对于非对称加密,可以选择RSA算法。同时,要注意密钥的生成和管理,确保密钥的安全性。
  • 基于密码的加密 :在收集用户密码时,使用 char 数组代替 String 对象,以避免密码信息的泄露。在生成PBE密钥和参数时,要确保盐和迭代次数的安全性和一致性。
  • 算法选择 :在选择算法时,要考虑算法的安全性、性能和应用场景。遵循标准的算法规范,确保不同实现之间的互操作性和安全性。

7.3 操作步骤总结表

操作类型 操作步骤
证书读取 1. 打开文件输入流
2. 根据文件格式选择读取方法(逐个读取或解析PKCS #7)
3. 生成并输出证书
加密操作 1. 生成密钥:使用 KeyGenerator 实例化并生成密钥
2. 创建密码器:指定算法、模式和填充方式
3. 初始化密码器:选择加密或解密模式
4. 执行加密或解密操作:调用 doFinal 方法
基于密码的加密 1. 收集用户密码:使用 readPasswd 方法
2. 生成盐和迭代次数:用于PBE加密
3. 创建PBE密钥规范和参数规范
4. 生成PBE密钥:使用 SecretKeyFactory
5. 创建并初始化PBE密码器
6. 执行加密操作

通过以上总结和建议,希望开发者能够更好地在Java中实现安全编程,保护系统和数据的安全。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值