Java RSA 数字签名实现与校验详解
数字签名是非对称加密的典型应用场景,利用私钥对数据进行签名,公钥负责验签,从而保证数据未被篡改且来源可信。下面通过一个完整的工具类演示如何在 Java 中实现这一过程。
密钥生成
首先需要生成 RSA 密钥对。这里使用 1024 位长度,实际生产中建议 2048 位以上。
public void generateKey() {
try {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
KeyPair kp = kpg.genKeyPair();
pbkey = kp.getPublic();
prkey = kp.getPrivate();
} catch (Exception e) {
e.printStackTrace();
}
}
签名与校验
签名时读取文件内容,用私钥计算摘要;校验时再次读取文件,用公钥比对签名结果。
public byte[] sign(String path) throws Exception {
FileInputStream f = new FileInputStream(path);
int num = f.available();
byte[] data = new byte[num];
f.read(data);
RSAPrivateKey prk = (RSAPrivateKey)prkey;
Signature s = Signature.getInstance("MD5WithRSA");
s.initSign(prk);
s.update(data);
return s.sign();
}
public void checkSign(String path, byte[] signeddata) throws Exception {
FileInputStream f = new FileInputStream(path);
int num = f.available();
byte[] data = new byte[num];
f.read(data);
RSAPublicKey pbk = (RSAPublicKey)pbkey;
Signature s = Signature.getInstance("MD5WithRSA");
s.initVerify(pbk);
s.update(data);
boolean ok = s.verify(signeddata);
System.out.println(ok ? "验证成功" : "验证失败");
}
测试示例
public static void main(String args[]) throws Exception {
DigitalSignDemo ds = new DigitalSignDemo();
ds.generateKey(); // 产生私钥和公钥
byte[] signeddata = ds.sign("test.txt"); // 文件签名
ds.checkSign("test.txt", signeddata); // 校验签名
}
注意:MD5 算法已不再推荐用于高安全场景,生产环境请改用 SHA256WithRSA。
