在数据传递过程中,一些非常重要的信息必须经过加密处理,防止其他人获取或者篡改信息。这就有了数字签名,数字签名处理的问题主要是两点
1、发送信息的人是真实确定的。
2、发送的信息是加密的且没有经过篡改的。
数字签名:保证数据发送人的正解性和发送内容没有经过篡改
数字摘要:发送的信息不是明文,别人获取到也难以解读信息。
1、数字签名
数字签名,就是只有信息的发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明。
数字签名技术是将摘要信息用发送者的私钥加密,与原文一起传送给接收者。接收者只有用发送者的公钥才能解密被加密的摘要信息,然后用HASH函数对收到的原文产生一个摘要信息,与解密的摘要信息对比。如果相同,则说明收到的信息是完整的,在传输过程中没有被修改,否则说明信息被修改过,因此数字签名能够验证信息的完整性。
数字签名是个加密的过程,数字签名验证是个解密的过程。
总结:
数字签名:还有密钥的消息摘要算法,比较出名的有RSA和DSA。
2、数字摘要
数字摘要是将任意长度的消息变成固定长度的短消息,它类似于一个自变量是消息的函数,也就是Hash函数。
数据摘要算法是密码学算法中非常重要的一个分支,它通过对所有数据提取指纹信息以实现数据签名、数据完整性校验等功能,由于其不可逆性,有时候会被用做敏感信息的加密。数据摘要算法也被称为哈希(Hash)算法、散列算法。
我们常见的有
1、MD2 、MD4、MD5
2、SHA1、SHA256、SHA384、SHA512
3、RSA的使用
关于RSA的一些比较详细的资料在阮一峰的的日志中有介绍
http://www.ruanyifeng.com/blog/2013/07/rsa_algorithm_part_two.html
RSA主要原理概括:两个很大的质数p和q的乘积n难以逆向求解
公钥私钥
公钥负责加密,私钥负责解密。
比如我需要别人给我一份加密文件,于是我生成一对公钥私钥,公钥发给别人,让别人加密,私钥我自己留着,当发送过来文件时,用私钥解密。
4、代码实现
public class RsaTest {
private static final String data="123";
public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
//1、生成密钥对
KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair=keyPairGenerator.generateKeyPair();
//2、从密钥对中获取公钥和私钥
PublicKey publicKey=keyPair.getPublic();
System.out.println("公钥:"+new String(Base64.getEncoder().encode(publicKey.getEncoded())));
PrivateKey privateKey=keyPair.getPrivate();
System.out.println("私钥:"+new String(Base64.getEncoder().encode(privateKey.getEncoded())));
//3、公钥加密
Cipher cipherEnc=Cipher.getInstance("RSA");
cipherEnc.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptBytes=cipherEnc.doFinal(data.getBytes());
System.out.println("加密后:"+new String(encryptBytes));
//4、私钥解密
Cipher cipherDec=Cipher.getInstance("RSA");
cipherDec.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptBytes=cipherDec.doFinal(encryptBytes);
System.out.println("解密后:"+new String(decryptBytes));
}
}
运行结果:
1、KeyPairGenerator 生成密钥对
KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair=keyPairGenerator.generateKeyPair();
- 使用KeyPairGenerator 每次生成的密钥都是随机的
- initialize()方法初始化密钥的长度,越长越安全
2、获取公钥,私钥
keyPair.getPublic()
keyPair.getPrivate()
3、Cipher
公钥和私钥都具备后,就可以使用加解密的工具类javax.crypto.Cipher对明文和密文进行处理了。与所有的引擎类一样,可以通过调用Cipher类中的getInstance(String transformation)静态工厂方法得到Cipher对象。