java数字签名_Java代码实现文件添加数字签名、验证数字签名

这个Java工具类提供RSA数字签名的加签和验签功能。通过使用`Signature.getInstance("SHA512withRSA")`进行签名和验证操作,支持从.pem文件中加载公钥和私钥。代码中包含了生成密钥对、加密解密以及文件的签名和验证的示例。
摘要由CSDN通过智能技术生成

importjavax.crypto.BadPaddingException;importjavax.crypto.Cipher;importjavax.crypto.IllegalBlockSizeException;importjavax.crypto.NoSuchPaddingException;import java.io.*;import java.security.*;importjava.security.interfaces.RSAPrivateKey;importjava.security.interfaces.RSAPublicKey;importjava.security.spec.InvalidKeySpecException;importjava.security.spec.PKCS8EncodedKeySpec;importjava.security.spec.X509EncodedKeySpec;importjava.util.Date;/*** 对文件加签、验签工具类

* 生成私钥:openssl genrsa -out rsa_private_key.pem 1024

* 私钥还不能直接被使用,需要进行PKCS#8编码:openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt

* 根据私钥生成公钥:openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

* 使用私钥sha512签名:openssl dgst -sha512 -sign rsa_private_key.pem -out xx.tar.gz.sign xx.tar.gz

* 使用公钥sha512验签:openssl dgst -verify rsa_public_key.pem -sha512 -signature xx.tar.gz.sign xx.tar.gz

*@authorXIHONGLIE

* @date 2018-03-27*/

public classRsaEncrypt {/*** rsa签名

*@paramdata 待签名的字符串

*@parampriKey rsa私钥字符串

*@return签名结果

*@throwsException 签名失败则抛出异常*/

public byte[] rsaSign(byte[] data, RSAPrivateKey priKey)throwsSignatureException {try{

Signature signature= Signature.getInstance("SHA512withRSA");

signature.initSign(priKey);

signature.update(data);byte[] signed =signature.sign();returnsigned;

}catch(Exception e) {throw new SignatureException("RSAcontent = " +data+ "; charset = ", e);

}

}/*** rsa验签

*@paramdata 被签名的内容

*@paramsign 签名后的结果

*@parampubKey rsa公钥

*@return验签结果

*@throwsSignatureException 验签失败,则抛异常*/

public boolean verify(byte[] data, byte[] sign, RSAPublicKey pubKey)throwsSignatureException {try{

Signature signature= Signature.getInstance("SHA512withRSA");

signature.initVerify(pubKey);

signature.update(data);returnsignature.verify(sign);

}catch(Exception e) {

e.printStackTrace();throw new SignatureException("RSA验证签名[content = " +data+ "; charset = " + "; signature = " + sign + "]发生异常!", e);

}

}/*** 私钥*/

privateRSAPrivateKey privateKey;/*** 公钥*/

privateRSAPublicKey publicKey;/*** 字节数据转字符串专用集合*/

private static final char[] HEX_CHAR = { '0', '1', '2', '3', '4', '5', '6','7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};/*** 获取私钥

*@return当前的私钥对象*/

publicRSAPrivateKey getPrivateKey() {returnprivateKey;

}/*** 获取公钥

*@return当前的公钥对象*/

publicRSAPublicKey getPublicKey() {returnpublicKey;

}/*** 随机生成密钥对*/

public voidgenKeyPair() {

KeyPairGenerator keyPairGen= null;try{

keyPairGen= KeyPairGenerator.getInstance("RSA");

}catch(NoSuchAlgorithmException e) {

e.printStackTrace();

}

keyPairGen.initialize(1024, newSecureRandom());

KeyPair keyPair=keyPairGen.generateKeyPair();this.privateKey =(RSAPrivateKey) keyPair.getPrivate();this.publicKey =(RSAPublicKey) keyPair.getPublic();

}/*** 从.pem文件中取得私钥

*@paramfilePath 文件路径

*@return私钥*/

publicString getPrivateKeyFromFile(String filePath){

String strPrivateKey= "";try{

BufferedReader privateKey= new BufferedReader(newFileReader(filePath));

String line= "";while((line = privateKey.readLine()) != null){

strPrivateKey+=line;

}

privateKey.close();

strPrivateKey= strPrivateKey.replace("-----BEGIN PRIVATE KEY-----","").replace("-----END PRIVATE KEY-----","");

}catch(Exception e){

e.printStackTrace();

}returnstrPrivateKey;

}/*** 从.pem文件中取得公钥

*@paramfilePath 文件路径

*@return公钥*/

publicString getPublicKeyFromFile(String filePath){

String strPublicKey= "";try{

BufferedReader publicKey= new BufferedReader(newFileReader(filePath));

String line= "";while((line = publicKey.readLine()) != null){

strPublicKey+=line;

}

publicKey.close();

strPublicKey= strPublicKey.replace("-----BEGIN PUBLIC KEY-----","").replace("-----END PUBLIC KEY-----","");

}catch(Exception e){

e.printStackTrace();

}returnstrPublicKey;

}/*** 从字符串中加载公钥

*@parampublicKeyStr 公钥数据字符串

*@throwsException 加载公钥时产生的异常*/

public void loadPublicKey(String publicKeyStr) throwsException {try{byte[] buffer =Base64Utils.decode(publicKeyStr);

KeyFactory keyFactory= KeyFactory.getInstance("RSA");

X509EncodedKeySpec keySpec= newX509EncodedKeySpec(buffer);this.publicKey =(RSAPublicKey) keyFactory.generatePublic(keySpec);

}catch(NoSuchAlgorithmException e) {throw new Exception("无此算法");

}catch(InvalidKeySpecException e) {throw new Exception("公钥非法");

}catch(NullPointerException e) {throw new Exception("公钥数据为空");

}

}/*** 加载私钥

*@paramprivateKeyStr 私钥文件名

*@return是否成功

*@throwsException*/

public void loadPrivateKey(String privateKeyStr) throwsException {try{byte[] buffer =Base64Utils.decode(privateKeyStr);

PKCS8EncodedKeySpec keySpec= newPKCS8EncodedKeySpec(buffer);

KeyFactory keyFactory= KeyFactory.getInstance("RSA");this.privateKey =(RSAPrivateKey) keyFactory.generatePrivate(keySpec);

}catch(NoSuchAlgorithmException e) {throw new Exception("无此算法");

}catch(InvalidKeySpecException e) {throw new Exception("私钥非法");

}catch(NullPointerException e) {throw new Exception("私钥数据为空");

}

}/*** 加密过程

*@parampublicKey 公钥

*@paramplainTextData 明文数据

*@return*@throwsException 加密过程中的异常信息*/

public byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData)throwsException {if (publicKey == null) {throw new Exception("加密公钥为空, 请设置");

}

Cipher cipher= null;try{

cipher= Cipher.getInstance("RSA");

cipher.init(Cipher.ENCRYPT_MODE, publicKey);byte[] output =cipher.doFinal(plainTextData);returnoutput;

}catch(NoSuchAlgorithmException e) {throw new Exception("无此加密算法");

}catch(NoSuchPaddingException e) {

e.printStackTrace();return null;

}catch(InvalidKeyException e) {throw new Exception("加密公钥非法,请检查");

}catch(IllegalBlockSizeException e) {throw new Exception("明文长度非法");

}catch(BadPaddingException e) {throw new Exception("明文数据已损坏");

}

}/*** 解密过程

*@paramprivateKey 私钥

*@paramcipherData 密文数据

*@return明文

*@throwsException 解密过程中的异常信息*/

public byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData)throwsException {if (privateKey == null) {throw new Exception("解密私钥为空, 请设置");

}

Cipher cipher= null;try{

cipher= Cipher.getInstance("RSA");

cipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] output =cipher.doFinal(cipherData);returnoutput;

}catch(NoSuchAlgorithmException e) {throw new Exception("无此解密算法");

}catch(NoSuchPaddingException e) {

e.printStackTrace();return null;

}catch(InvalidKeyException e) {throw new Exception("解密私钥非法,请检查");

}catch(IllegalBlockSizeException e) {throw new Exception("密文长度非法");

}catch(BadPaddingException e) {throw new Exception("密文数据已损坏");

}

}/*** 字节数据转十六进制字符串

*@paramdata 输入数据

*@return十六进制内容*/

public static String byteArrayToString(byte[] data) {

StringBuilder stringBuilder= newStringBuilder();for (int i = 0; i < data.length; i++) {//取出字节的高四位 作为索引得到相应的十六进制标识符 注意无符号右移

stringBuilder.append(HEX_CHAR[(data[i] & 0xf0) >>> 4]);//取出字节的低四位 作为索引得到相应的十六进制标识符

stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);if (i < data.length - 1) {

stringBuilder.append(' ');

}

}returnstringBuilder.toString();

}/*** btye转换hex函数

*@parambyteArray

*@return

*/

public static String byteToHex(byte[] byteArray) {

StringBuffer strBuff= newStringBuffer();for (int i = 0; i < byteArray.length; i++) {if (Integer.toHexString(0xFF & byteArray[i]).length() == 1) {

strBuff.append("0").append(

Integer.toHexString(0xFF &byteArray[i]));

}else{

strBuff.append(Integer.toHexString(0xFF &byteArray[i]));

}

}returnstrBuff.toString();

}/*** 以字节为单位读取文件,常用于读二进制文件,如图片、声音、影像等文件。*/

public static byte[] readFileByBytes(String fileName) {

File file= newFile(fileName);

InputStream in= null;byte[] txt = new byte[(int) file.length()];try{//一次读一个字节

in = newFileInputStream(file);inttempbyte;int i = 0;while ((tempbyte = in.read()) != -1) {

txt[i]= (byte) tempbyte;

i++;

}

in.close();returntxt;

}catch(IOException e) {

e.printStackTrace();returntxt;

}

}/*** Main 测试方法

*@paramargs*/

public static voidmain(String[] args) {

RsaEncrypt rsaEncrypt= newRsaEncrypt();try{

String publicKey= "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDPTrsUJ26WDSEQwKuAJhQ6XTNHKl1/+bWeyKRQKb0jeCyuiChMxN/qYSgg2BvS2bP51Rb5P9/UE1Rxm5drr3RYNMDvQoXBuA+rHiUX3wkdXmWSaktVbfe5C95N5FCF2jyLMIuWmrMk6Wo3r5MXrCb54A6zU7SzO/r7F0VkpBh9KwIDAQAB";

rsaEncrypt.loadPublicKey(publicKey);

System.out.println("加载公钥成功");

}catch(Exception e) {

System.err.println(e.getMessage());

System.err.println("加载公钥失败");

}//加载私钥

try{

String privateKey= "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAM9OuxQnbpYNIRDAq4AmFDpdM0cqXX/5tZ7IpFApvSN4LK6IKEzE3+phKCDYG9LZs/nVFvk/39QTVHGbl2uvdFg0wO9ChcG4D6seJRffCR1eZZJqS1Vt97kL3k3kUIXaPIswi5aasyTpajevkxesJvngDrNTtLM7+vsXRWSkGH0rAgMBAAECgYAlnFEQnP7RNlyTX4E95Kqy1AnjlWoVN8adoiU9bfUkpD7nA0jcdLNzIGFZZBvYKysd3m0ml1ISdddSLTpRjSl8K6O9dJDud3G9Oh3qCGgFflcKuKEXDnlaooX1sBrWF5vS0Gvg98x2C52Pnblm2eGVuTvCMaINDZLaamUlaFldMQJBAO3clhAIBJSWlm7Tt/a1d7+IbsGcS16Rk/N23DHg6LADXxIezxgSrpztSa5Nq81W5RC2WsotYYeRt+8KHsPRRn8CQQDfHa7A7hBTOT/V4FXTApuJUlReUh6cHWPsrxf/rUYKylK9WYBAJv1AZW9KaRtcadyu7ldNMb3MAsbE2vLoW2tVAkEAxhvLAF8tMXSapoO/3MMXkXbYiHjcbU9iooyEqSZhpven3ze51Jr6w8j+bSZTyRpufpTi2TEi4f8D6xvKs91BkQJBAKLS05xiX7GMfwSDQb7LEVzmo0FuJn6BiFHK+fWRqyLmwfkDHvAyQ/FB1TT1fY00iGN09msUWNFQWWSB8HEXfj0CQQCAJYV35rNJ781DXhBH5m1tq74zDNzAqynjm0hqhzlVMSHTYFIeU6SBnhk3swnfvJ8kgy3bQJtohYZ8Tuaz19VN";

rsaEncrypt.loadPrivateKey(privateKey);

System.out.println("加载私钥成功");

}catch(Exception e) {

System.err.println(e.getMessage());

System.err.println("加载私钥失败");

}//测试字符串

String encryptStr = "12321dsfasf1321312fsfdsafsdafasfsadf";try{

System.out.println(newDate());//加密

byte[] cipher =rsaEncrypt.encrypt(rsaEncrypt.getPublicKey(),

encryptStr.getBytes());//解密

byte[] plainText =rsaEncrypt.decrypt(rsaEncrypt.getPrivateKey(),

cipher);

System.out.println(newDate());

System.out.println(newString(plainText));byte[] content = readFileByBytes("/data/zhnx/IN/data_xinbao.tar.gz");//签名验证

byte[] signbyte =rsaEncrypt.rsaSign(content, rsaEncrypt.getPrivateKey());

System.out.println("签名-----:" +byteToHex(signbyte));

ByteUtil.saveFile(signbyte,"/data/zhnx/IN/","data_xinbao1.tar.gz.sign");

Boolean isok=rsaEncrypt.verify(content, signbyte, rsaEncrypt.getPublicKey());

System.out.println("验证:" +isok);//读取验证文件

byte[] read = readFileByBytes("/data/zhnx/IN/data_xinbao.tar.gz.sign");

System.out.println("读取签名文件:" +byteToHex(read));

Boolean isfok=rsaEncrypt.verify(content, read, rsaEncrypt.getPublicKey());

System.out.println("文件验证2:" +isfok);

}catch(Exception e) {

System.err.println(e.getMessage());

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值