java - 对 Java 中的文件执行签名和验证操作时出错
问题描述
我正在使用 java 执行签名和验证操作并得到以下错误
java.security.SignatureException:签名长度不正确:得到 155 但预期为 128
请在下面找到我的代码以进行签名和验证
添加签名
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.nio.file.Files;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.Security;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
public class AddSignature {
//The constructor of Message class builds the list that will be written to the file. The list consists of the message and the signature.
public AddSignature(String data, String keyFile) throws InvalidKeyException, Exception {
sign(data, keyFile);
}
//The method that signs the data using the private key that is stored in keyFile path
public void sign(String data, String keyFile) throws InvalidKeyException, Exception{
Signature dsa = Signature.getInstance("SHA1withRSA");
dsa.initSign(getPrivate(keyFile));
dsa.update(data.getBytes());
writeToFile("encrypt//destination//data.txt", data.getBytes());
byte[] sign = dsa.sign();
writeToFile("encrypt//destination//signed.txt", sign);
}
//Method to retrieve the Private Key from a file
public PrivateKey getPrivate(String filename) throws Exception {
byte[] keyBytes = Files.readAllBytes(new File(filename).toPath());
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(spec);
}
private void writeToFile(String signedFileLocation, byte[] signedData) throws FileNotFoundException, IOException {
File f = new File(signedFileLocation);
f.getParentFile().mkdirs();
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(signedFileLocation));
out.writeObject(signedData);
out.close();
}
public static void main(String[] args) throws InvalidKeyException, IOException, Exception{
String data = JOptionPane.showInputDialog("Type your message here");
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
new AddSignature(data, "MyKeys/privateKey");
}}
验证签名
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
public class VerifySignature {
private static boolean verifySignature(byte[] data, byte[] signature, String keyFile) throws Exception {
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initVerify(getPublic(keyFile));
sig.update(data);
try {
return sig.verify(signature);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public static byte[] read(String fileName) throws IOException {
FileInputStream fin = null;
try {
File file = new File(fileName);
fin = new FileInputStream(file);
byte fileContent[] = new byte[(int) file.length()];
fin.read(fileContent);
return fileContent;
} catch (Exception e) {
throw e;
} finally {
fin.close();
}
}
// Method to retrieve the Public Key from a file
public static PublicKey getPublic(String filename) throws Exception {
byte[] keyBytes = Files.readAllBytes(new File(filename).toPath());
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);
}
public static void main(String[] args) throws Exception {
byte[] data = read("encrypt//destination//data.txt");
byte[] signed = read("encrypt//destination//signed.txt");
verifySignature(data, signed, "MyKeys/publicKey");
}
}
我需要签署一个文件并保存在一个位置,并且需要检索相同的文件来验证签名
解决方案
当您从文件中检索私钥时出现错误。你可以试试这样:
public PrivateKey getPrivate(String filename) throws Exception {
//byte[] keyBytes = Files.readAllBytes(new File(filename).toPath());
byte[] keyBytes = Base64Utils.decode(readFile(filename));
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(spec);
}
private static String readFile(String filePath) throws Exception {
File inFile = new File(filePath);
long fileLen = inFile.length();
Reader reader = new FileReader(inFile);
char[] content = new char[(int) fileLen];
reader.read(content);
System.out.println("read content:" + new String(content));
return new String(content);
}
推荐阅读
- mysql - MySQL Workbench 无法导出数据
- java - 如何使用 Spring Boot 在模板化的 excel 文件中附加 JSON 数据?
- domain-driven-design - 处理跨聚合关系和聚合状态中的事件
- c# - 在带有 .json 的控制器 Web api Uri 中找不到资源
- javascript - 为什么 Angular 项目中没有 Angular-CLI 为“模型”生成命令?
- sql-server - 连接 Azure SQL 数据库上的其他 SQL 数据库
- raml - RAML 1.0:在可选对象中定义 minProperties
- ios - 在 Swift 4 中调用 collectionView(_ :layout:sizeForItemAt:)
- xamarin - 在适用于 Android 和 iOS 的 Xamarin.Forms 中发送带附件的电子邮件
- angular - 将对象数组转换为单个字符串并将其推入同一数组