数字签名介绍和java的实现
程序员文章站
2024-03-19 13:00:58
...
现实中的文件和书信我们可以通过印章来确定它的有效和可信性,那么在计算机网络中传送的报文如何保证呢?这就是数字签名要解决的问题。
数字签名必须能保证以下3点
1.接收者能够核实发送者对报文的签名。
2.发送者事后不能抵赖对报文的签名。
3.接收者不能伪造对报文的签名。
目前已经存在着各种各样数字签名方法。今天为大家介绍一种java中比较容易实现的公开**算法来做数字签名。首先介绍一下公开**算法实现数字签名的原理:
公开**算法有以下特点:
1.加***PK对明文X加密后,用解***SK解密即可恢复出原明文。另外加密和解密运算可以互换。
公式为:Dsk(Epk(X))=X 和Epk(Dsk(X))=X
2.加***PK是公开的,但通过PK无法推导出SK
这2个特点正好满足了数字签名的3点要求。下图是用公开**算法实现数字签名的原理图
有了以上的知识用java来实现这个数字签名就很容易了,通过java.security里面有RSA和DSA公开**算法的实现。
下面是部分代码
generateKeypair方法生成PK和SK,你只需要把SK保存下来用
public static void generateKeypair() {
KeyPairGenerator ******;
FileOutputStream out = null;
try {
****** = KeyPairGenerator.getInstance("DSA");// 指定使用DSA算法
******.initialize(1024, new SecureRandom());
KeyPair pair = ******.generateKeyPair();
pk = pair.getPublic();
sk = pair.getPrivate();
out = new FileOutputStream(System.getProperty("user.dir")
+ "\\sk.dat");
String tmpsk = StringUtil.encodeHex(sk.getEncoded());
out.write(tmpsk.getBytes());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (out != null)
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
generateSignature方法通过sk对明文进行签名,返回值是对明文的签名
public String generateSignature(File inFile, PrivateKey privKey) {
Signature dsa;
FileInputStream fis = null;
try {
dsa = Signature.getInstance("DSA");
dsa.initSign(privKey);
fis = new FileInputStream(inFile);
SAXReader reader = new SAXReader();
Document doc = reader.read(fis);
dsa.update(doc.asXML().getBytes());
byte[] signature = dsa.sign();
return StringUtil.encodeHex(signature);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
} finally {
try {
if (fis != null)
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
validData方法对收到的数据进行签名验证
public boolean validData (byte[] data,String publicKey,String signature) {
try { // valid the file with public key and signature
byte[] encodedpubKey = StringUtil.decodeHex(publicKey);
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(
encodedpubKey);
KeyFactory keyFactory;
keyFactory = KeyFactory.getInstance("DSA");
PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);
byte[] sign = StringUtil.decodeHex(signature);
Signature s = Signature.getInstance("DSA");
s.initVerify(pubKey);
s.update(data);
boolean flag = s.verify(sign);
return flag;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace();
}
return false;
}
推荐阅读
-
[转]Java 数字签名(Digital Signature)的批处理文件制作
-
Java PDF数字签名(三)——获取PDF中的数字签名信息
-
数字签名介绍和java的实现
-
通过Java JDK实现数字签名ECDSA算法
-
java---数字签名的案例
-
Android - adb forward实现PC和App的Socket通讯 博客分类: 【57】、Android
-
RSA算法加密和签名详解---java实现
-
模拟登陆百度的Java实现 博客分类: Java 爬虫 采集 爬虫百度指数数据采集采集
-
JAVA 8的Lambda表达式和Stream API研究 博客分类: Java编程
-
JAVA 8的Lambda表达式和Stream API研究 博客分类: Java编程