数据签名和验签

2023年 2月 15日22:30:15 发表评论

其他用户用他的公共密钥 (pubkey) 和签名 (signed) 和信息 (info) 进行验证是否由他签名的信息

读入公钥 
java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("mypubkey.dat")); 
PublicKey pubkey=(PublicKey)in.readObject(); 
in.close();

读入签名和信息 
in=new java.io.ObjectInputStream(new java.io.FileInputStream("myinfo.dat")); 
String info=(String)in.readObject(); 
byte[] signed=(byte[])in.readObject(); 
in.close();

初始一个 Signature 对象 , 并用公钥和签名进行验证 
java.security.Signature signetcheck=java.security.Signature.getInstance("DSA"); 
signetcheck.initVerify(pubkey); 
signetcheck.update(info.getBytes()); 
if (signetcheck.verify(signed)) { System.out.println("签名正常");}

// 使用公钥将signed进行解签,然后与info比较是否相等,相等则签名正确。即保证是指定人发送,也保证信息传输中没有被修改。如果被修改,那么修改后的info肯定与解签后的值不相等,验证签名失败。

对于密钥的保存本文是用对象流的方式保存和传送的 , 也可可以用编码的方式保存 . 注意要 
import java.security.spec.* 
import java.security.*

=以下为学习网址中的内容==========================================================================

 

第 1 章基础知识

 

单钥密码体制是一种传统的加密算法,是指信息的发送方和接收方共同使用同一把密钥进行加解密。

通常 , 使用的加密算法 比较简便高效 , 密钥简短,加解密速度快,破译极其困难。但是加密的安全性依靠密钥保管的安全性 , 在公开的计算机网络上安全地传送和保管密钥是一个严峻的问题,并且如果在多用户的情况下密钥的保管安全性也是一个问题。

单钥密码体制的代表是美国的 DES

一个消息摘要就是一个数据块的数字指纹。即对一个任意长度的一个数据块进行计算,产生一个唯一指印(对于 SHA1 是产生一个 20 字节的二进制数组)。

消息摘要有两个基本属性:

  • 两个不同的报文难以生成相同的摘要
  • 难以对指定的摘要生成一个报文,而由该报文反推算出该指定的摘要

代表:美国国家标准技术研究所的 SHA1 和麻省理工学院 Ronald Rivest 提出的 MD5

密钥一致协议是由公开密钥密码体制的奠基人 Diffie 和 Hellman 所提出的一种思想。

先决条件 , 允许两名用户在公开媒体上交换信息以生成"一致"的 , 可以共享的密钥

代表:指数密钥一致协议 (Exponential Key Agreement Protocol)

1976 年,Dittie 和 Hellman 为解决密钥管理问题,在他们的奠基性的工作"密码学的新方向"一文中,提出一种密钥交换协议,允许在不安全的媒体上通过通讯双方交换信息,安全地传送秘密密钥。在此新思想的基础上,很快出现了非对称密钥密码体制,即公钥密码体制。在公钥体制中,加密密钥不同于解密密钥,加密密钥公之于众,谁都可以使用;解密密钥只有解密人自己知道。它们分别称为公开密钥(Public key)和秘密密钥(Private key)。

迄今为止的所有公钥密码体系中,RSA 系统是最著名、最多使用的一种。RSA 公开密钥密码系统是由 R.Rivest、A.Shamir 和 L.Adleman 俊教授于 1977 年提出的。RSA 的取名就是来自于这三位发明者的姓的第一个字母

所谓数字签名就是信息发送者用其私钥对从所传报文中提取出的特征数据(或称数字指纹)进行 RSA 算法操作,以保证发信人无法抵赖曾发过该信息(即不可抵赖性),同时也确保信息报文在经签名后末被篡改(即完整性)。当信息接收者收到报文后,就可以用发送者的公钥对数字签名进行验证。

在数字签名中有重要作用的数字指纹是通过一类特殊的散列函数(HASH 函数)生成的,对这些 HASH 函数的特殊要求是:

代表:DSA

 

第 2 章在 JAVA 中的实现

Diffie-Hellman 密钥一致协议和 DES 程序需要 JCE 工具库的支持 , 可以到 http://java.sun.com/security/index.html 下载 JCE, 并进行安装。简易安装把 jce1.2.1\lib 下的所有内容复制到 %java_home%\lib\ext 下 , 如果没有 ext 目录自行建立 , 再把 jce1_2_1.jar 和 sunjce_provider.jar 添加到 CLASSPATH 内 , 更详细说明请看相应用户手册

使用方法 :

首先用生成一个 MessageDigest 类 , 确定计算方法

java.security.MessageDigest alga=java.security.MessageDigest.getInstance("SHA-1");

添加要进行计算摘要的信息

alga.update(myinfo.getBytes());

计算出摘要

byte[] digesta=alga.digest();

发送给其他人你的信息和摘要

其他人用相同的方法初始化 , 添加信息 , 最后进行比较摘要是否相同

algb.isEqual(digesta,algb.digest())

相关 AIP

java.security.MessageDigest 类

static getInstance(String algorithm)

返回一个 MessageDigest 对象 , 它实现指定的算法

参数 : 算法名 , 如 SHA-1 或 MD5

void update (byte input)

void update (byte[] input)

void update(byte[] input, int offset, int len)

添加要进行计算摘要的信息

byte[] digest()

完成计算 , 返回计算得到的摘要 ( 对于 MD5 是 16 位 ,SHA 是 20 位 )

void reset()

复位

static boolean isEqual(byte[] digesta, byte[] digestb)

比效两个摘要是否相同

代码:

首先生成密钥 , 并保存 ( 这里并没的保存的代码 , 可参考 DSA 中的方法 )

KeyGenerator keygen = KeyGenerator.getInstance(Algorithm);

SecretKey deskey = keygen.generateKey();

用密钥加密明文 (myinfo), 生成密文 (cipherByte)

Cipher c1 = Cipher.getInstance(Algorithm);

c1.init(Cipher.ENCRYPT_MODE,deskey);

byte[] cipherByte=c1.doFinal(myinfo.getBytes());

传送密文和密钥 , 本文没有相应代码可参考 DSA

.............

用密钥解密密文

c1 = Cipher.getInstance(Algorithm);

c1.init(Cipher.DECRYPT_MODE,deskey);

byte[] clearByte=c1.doFinal(cipherByte);

相对来说对称密钥的使用是很简单的 , 对于 JCE 来讲支技 DES,DESede,Blowfish 三种加密术

对于密钥的保存各传送可使用对象流或者用二进制编码 , 相关参考代码如下

相关 API

KeyGenerator 在 DSA 中已经说明 , 在添加 JCE 后在 instance 进可以如下参数

DES,DESede,Blowfish,HmacMD5,HmacSHA1

javax.crypto.Cipher 加 / 解密器

返回一个指定方法的 Cipher 对象

参数 :transformation 方法名 ( 可用 DES,DESede,Blowfish)

public final void init(int opmode, java.security.Key key) 
throws java.security.InvalidKeyException

用指定的密钥和模式初始化 Cipher 对象

参数 :opmode 方式 (ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE,UNWRAP_MODE)

key 密钥

对 input 内的串 , 进行编码处理 , 返回处理后二进制串 , 是返回解密文还是加解文由 init 时的 opmode 决定

注意 : 本方法的执行前如果有 update, 是对 updat 和本次 input 全部处理 , 否则是本 inout 的内容

公开密钥密码体制的奠基人 Diffie 和 Hellman 所提出的 "指数密钥一致协议"(Exponential Key Agreement Protocol), 该协议不要求别的安全性 先决条件 , 允许两名用户在公开媒体上交换信息以生成"一致"的 , 可以共享的密钥。在 JCE 的中实现用户 alice 生成 DH 类型的密钥对 , 如果长度用 1024 生成的时间请 , 推荐第一次生成后保存 DHParameterSpec, 以便下次使用直接初始化 . 使其速度加快

alice 生成公钥发送组 bob

bob 从 alice 发送来的公钥中读出 DH 密钥对的初始参数生成 bob 的 DH 密钥对

注意这一步一定要做 , 要保证每个用户用相同的初始参数生成的

bob 根据 alice 的公钥生成本地的 DES 密钥

bob 已经生成了他的 DES 密钥 , 他现把他的公钥发给 alice,

alice 根据 bob 的公钥生成本地的 DES 密钥

bob 和 alice 能过这个过程就生成了相同的 DES 密钥 , 在这种基础就可进行安全能信

常用 API

java.security.KeyPairGenerator 密钥生成器类 
public static KeyPairGenerator getInstance(String algorithm) 
throws NoSuchAlgorithmException 
以指定的算法返回一个 KeyPairGenerator 对象 
参数 : algorithm 算法名 . 如 : 原来是 DSA, 现在添加了 DiffieHellman(DH)

public void initialize(int keysize) 
以指定的长度初始化 KeyPairGenerator 对象 , 如果没有初始化系统以 1024 长度默认设置 
参数 :keysize 算法位长 . 其范围必须在 512 到 1024 之间,且必须为 64 的倍数 
注意 : 如果用 1024 生长的时间很长 , 最好生成一次后就保存 , 下次就不用生成了

public void initialize(AlgorithmParameterSpec params) 
throws InvalidAlgorithmParameterException 
以指定参数初始化

javax.crypto.interfaces.DHPublicKey 
public DHParameterSpec getParams() 
返回 
java.security.KeyFactory

public static KeyFactory getInstance(String algorithm) 
throws NoSuchAlgorithmException 
以指定的算法返回一个 KeyFactory 
参数 : algorithm 算法名 :DSH,DH

public final PublicKey generatePublic(KeySpec keySpec) 
throws InvalidKeySpecException 
根据指定的 key 说明 , 返回一个 PublicKey 对象

java.security.spec.X509EncodedKeySpec 
public X509EncodedKeySpec(byte[] encodedKey) 
根据指定的二进制编码的字串生成一个 key 的说明 
参数 :encodedKey 二进制编码的字串 ( 一般能过 PublicKey.getEncoded() 生成 ) 
javax.crypto.KeyAgreement 密码一至类

public static final KeyAgreement getInstance(java.lang.String algorithm) 
throws java.security.NoSuchAlgorithmException 
返回一个指定算法的 KeyAgreement 对象 
参数 :algorithm 算法名 , 现在只能是 DiffieHellman(DH)

public final void init(java.security.Key key) 
throws java.security.InvalidKeyException 
用指定的私钥初始化 
参数 :key 一个私钥

public final java.security.Key doPhase(java.security.Key key, 
boolean lastPhase) 
throws java.security.InvalidKeyException, 
java.lang.IllegalStateException 
用指定的公钥进行定位 ,lastPhase 确定这是否是最后一个公钥 , 对于两个用户的 
情况下就可以多次定次 , 最后确定 
参数 :key 公钥 
lastPhase 是否最后公钥

public final SecretKey generateSecret(java.lang.String algorithm) 
throws java.lang.IllegalStateException, 
java.security.NoSuchAlgorithmException, 
java.security.InvalidKeyException 
根据指定的算法生成密钥 
参数 :algorithm 加密算法 ( 可用 DES,DESede,Blowfish)

 

第 3 章小结

在加密术中生成密钥对时,密钥对的当然是越长越好,但费时也越多,请从中从实际出发选取合适的长度,大部分例码中的密钥是每次运行就从新生成,在实际的情况中是生成后在一段时间保存在文件中,再次运行直接从文件中读入,从而加快速度。当然定时更新和加强密钥保管的安全性也是必须的。

原文链接:https://www.cnblogs.com/zuoqun/p/8074956.html

  • 版权声明:内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件至 1936370309@qq.com 举报,一经查实,本站将立刻删除。
  • 转载请注明:数据签名和验签 紫林博客

发表评论

您必须才能发表评论!