Java中常用的加密方法(JDK)

加密,是以某种特殊的算法改变原有的信息数据,使得未授权的用户即使获得了已加密的信息,但因不知解密的方法,仍然无法了解信息的内容。大体上分为[b]双向加密[/b]和[b]单向加密[/b],而双向加密又分为[b]对称加密[/b]和[b]非对称加密[/b](有些资料将加密直接分为对称加密和非对称加密)。

双向加密大体意思就是明文加密后形成密文,可以通过算法还原成明文。而单向加密只是对信息进行了摘要计算,不能通过算法生成明文,单向加密从严格意思上说不能算是加密的一种,应该算是摘要算法吧。具体区分可以参考:
(本人解释不清呢 …… )
[url]http://security.group.iteye.com/group/wiki/1710-one-way-encryption-algorithm[/url]
[b]一、双向加密[/b]
[b](一)、对称加密[/b]
采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。
需要对加密和解密使用相同密钥的加密算法。由于其速度,对称性加密通常在消息发送方需要加密大量数据时使用。对称性加密也称为密钥加密。
所谓对称,就是采用这种加密方法的双方使用方式用同样的密钥进行加密和解密。密钥是控制加密及解密过程的指令。

算法是一组规则,规定如何进行加密和解密。因此对称式加密本身不是安全的。   
常用的对称加密有:DES、IDEA、RC2、RC4、SKIPJACK、RC5、AES算法等

对称加密一般java类中中定义成员

//KeyGenerator 提供对称密钥生成器的功能,支持各种算法
private KeyGenerator keygen;
//SecretKey 负责保存对称密钥
private SecretKey deskey;
//Cipher负责完成加密或解密工作
private Cipher c;
//该字节数组负责保存加密的结果
private byte[] cipherByte;


在构造函数中初始化

Security.addProvider(new com.sun.crypto.provider.SunJCE());
//实例化支持DES算法的密钥生成器(算法名称命名需按规定,否则抛出异常)
keygen = KeyGenerator.getInstance("DES");//
//生成密钥
deskey = keygen.generateKey();
//生成Cipher对象,指定其支持的DES算法
c = Cipher.getInstance("DES");



[b]1. DES[/b]算法为密码体制中的对称密码体制,又被成为美国数据加密标准,是1972年美国IBM公司研制的对称密码体制加密算法。 明文按64位进行分组, 密钥长64位,密钥事实上是56位参与DES运算(第8、16、24、32、40、48、56、64位是校验位, 使得每个密钥都有奇数个1)分组后的明文组和56位的密钥按位替代或交换的方法形成密文组的加密方法。


import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

public class EncrypDES {

//KeyGenerator 提供对称密钥生成器的功能,支持各种算法
private KeyGenerator keygen;
//SecretKey 负责保存对称密钥
private SecretKey deskey;
//Cipher负责完成加密或解密工作
private Cipher c;
//该字节数组负责保存加密的结果
private byte[] cipherByte;

public EncrypDES() throws NoSuchAlgorithmException, NoSuchPaddingException{
Security.addProvider(new com.sun.crypto.provider.SunJCE());
//实例化支持DES算法的密钥生成器(算法名称命名需按规定,否则抛出异常)
keygen = KeyGenerator.getInstance("DES");
//生成密钥
deskey = keygen.generateKey();
//生成Cipher对象,指定其支持的DES算法
c = Cipher.getInstance("DES");
}

/**
* 对字符串加密
*
* @param str
* @return
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
public byte[] Encrytor(String str) throws InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
// 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式
c.init(Cipher.ENCRYPT_MODE, deskey);
byte[] src = str.getBytes();
// 加密,结果保存进cipherByte
cipherByte = c.doFinal(src);
return cipherByte;
}

/**
* 对字符串解密
*
* @param buff
* @return
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
public byte[] Decryptor(byte[] buff) throws InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
// 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式
c.init(Cipher.DECRYPT_MODE, deskey);
cipherByte = c.doFinal(buff);
return cipherByte;
}

/**
* @param args
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws InvalidKeyException
*/
public static void main(String[] args) throws Exception {
EncrypDES de1 = new EncrypDES();
String msg ="郭XX-搞笑相声全集";
byte[] encontent = de1.Encrytor(msg);
byte[] decontent = de1.Decryptor(encontent);
System.out.println("明文是:" + msg);
System.out.println("加密后:" + new String(encontent));
System.out.println("解密后:" + new String(decontent));
}

}


[b]2. 3DES[/b]又称Triple DES,是DES加密算法的一种模式,它使用3条56位的密钥对3DES
数据进行三次加密。数据加密标准(DES)是美国的一种由来已久的加密标准,它使用对称密钥加密法,并于1981年被ANSI组织规范为ANSI X.3.92。DES使用56位密钥和密码块的方法,而在密码块的方法中,文本被分成64位大小的文本块然后再进行加密。比起最初的DES,3DES更为安全。   
3DES(即Triple DES)是DES向AES过渡的加密算法(1999年,NIST将3-DES指定为过渡的加密标准),是DES的一个更安全的变形。它以DES为基本模块,通过组合分组方法设计出分组加密算法,其具体实现如下:
设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,P代表明文,C代表密文,
这样,   
3DES加密过程为:C=Ek3(Dk2(Ek1(P)))
3DES解密过程为:P=Dk1((EK2(Dk3(C)))

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

public class EncrypDES3 {

// KeyGenerator 提供对称密钥生成器的功能,支持各种算法
private KeyGenerator keygen;
// SecretKey 负责保存对称密钥
private SecretKey deskey;
// Cipher负责完成加密或解密工作
private Cipher c;
// 该字节数组负责保存加密的结果
private byte[] cipherByte;

public EncrypDES3() throws NoSuchAlgorithmException, NoSuchPaddingException {
Security.addProvider(new com.sun.crypto.provider.SunJCE());
// 实例化支持DES算法的密钥生成器(算法名称命名需按规定,否则抛出异常)
keygen = KeyGenerator.getInstance("DESede");
// 生成密钥
deskey = keygen.generateKey();
// 生成Cipher对象,指定其支持的DES算法
c = Cipher.getInstance("DESede");
}

/**
* 对字符串加密
*
* @param str
* @return
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
public byte[] Encrytor(String str) throws InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
// 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式
c.init(Cipher.ENCRYPT_MODE, deskey);
byte[] src = str.getBytes();
// 加密,结果保存进cipherByte
cipherByte = c.doFinal(src);
return cipherByte;
}

/**
* 对字符串解密
*
* @param buff
* @return
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
public byte[] Decryptor(byte[] buff) throws InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
// 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式
c.init(Cipher.DECRYPT_MODE, deskey);
cipherByte = c.doFinal(buff);
return cipherByte;
}

/**
* @param args
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws InvalidKeyException
*/
public static void main(String[] args) throws Exception {
EncrypDES3 des = new EncrypDES3();
String msg ="郭XX-搞笑相声全集";
byte[] encontent = des.Encrytor(msg);
byte[] decontent = des.Decryptor(encontent);
System.out.println("明文是:" + msg);
System.out.println("加密后:" + new String(encontent));
System.out.println("解密后:" + new String(decontent));

}

}


[b]3. AES[/b]密码学中的高级加密标准(Advanced Encryption Standard,AES),又称 高级加密标准
Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。   该算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,以Rijndael之命名之,投稿高级加密标准的甄选流程。(Rijdael的发音近于 "Rhinedoll"。)


import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

public class EncrypAES {

//KeyGenerator 提供对称密钥生成器的功能,支持各种算法
private KeyGenerator keygen;
//SecretKey 负责保存对称密钥
private SecretKey deskey;
//Cipher负责完成加密或解密工作
private Cipher c;
//该字节数组负责保存加密的结果
private byte[] cipherByte;

public EncrypAES() throws NoSuchAlgorithmException, NoSuchPaddingException{
Security.addProvider(new com.sun.crypto.provider.SunJCE());
//实例化支持DES算法的密钥生成器(算法名称命名需按规定,否则抛出异常)
keygen = KeyGenerator.getInstance("AES");
//生成密钥
deskey = keygen.generateKey();
//生成Cipher对象,指定其支持的DES算法
c = Cipher.getInstance("AES");
}

/**
* 对字符串加密
*
* @param str
* @return
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
public byte[] Encrytor(String str) throws InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
// 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式
c.init(Cipher.ENCRYPT_MODE, deskey);
byte[] src = str.getBytes();
// 加密,结果保存进cipherByte
cipherByte = c.doFinal(src);
return cipherByte;
}

/**
* 对字符串解密
*
* @param buff
* @return
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
public byte[] Decryptor(byte[] buff) throws InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
// 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式
c.init(Cipher.DECRYPT_MODE, deskey);
cipherByte = c.doFinal(buff);
return cipherByte;
}

/**
* @param args
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws InvalidKeyException
*/
public static void main(String[] args) throws Exception {
EncrypAES de1 = new EncrypAES();
String msg ="郭XX-搞笑相声全集";
byte[] encontent = de1.Encrytor(msg);
byte[] decontent = de1.Decryptor(encontent);
System.out.println("明文是:" + msg);
System.out.println("加密后:" + new String(encontent));
System.out.println("解密后:" + new String(decontent));
}

}


[b](二)、非对称加密[/b]
1976年,美国学者Dime和Henman为解决信息公开传送和密钥管理问题,提出一种新的密钥交换协议,允许在不安全的媒体上的通讯双方交换信息,安全地达成一致的密钥,这就是“公开密钥系统”。相对于“对称加密算法”这种方法也叫做“非对称加密算法”。 与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥
(privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。

[b]1. RSA[/b] 公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。

import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

public class EncrypRSA {

/**
* 加密
* @param publicKey
* @param srcBytes
* @return
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
protected byte[] encrypt(RSAPublicKey publicKey,byte[] srcBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
if(publicKey!=null){
//Cipher负责完成加密或解密工作,基于RSA
Cipher cipher = Cipher.getInstance("RSA");
//根据公钥,对Cipher对象进行初始化
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] resultBytes = cipher.doFinal(srcBytes);
return resultBytes;
}
return null;
}

/**
* 解密
* @param privateKey
* @param srcBytes
* @return
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
protected byte[] decrypt(RSAPrivateKey privateKey,byte[] srcBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
if(privateKey!=null){
//Cipher负责完成加密或解密工作,基于RSA
Cipher cipher = Cipher.getInstance("RSA");
//根据公钥,对Cipher对象进行初始化
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] resultBytes = cipher.doFinal(srcBytes);
return resultBytes;
}
return null;
}

/**
* @param args
* @throws NoSuchAlgorithmException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
*/
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
EncrypRSA rsa = new EncrypRSA();
String msg = "郭XX-精品相声";
//KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
//初始化密钥对生成器,密钥大小为1024位
keyPairGen.initialize(1024);
//生成一个密钥对,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
//得到私钥
RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();
//得到公钥
RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();

//用公钥加密
byte[] srcBytes = msg.getBytes();
byte[] resultBytes = rsa.encrypt(publicKey, srcBytes);

//用私钥解密
byte[] decBytes = rsa.decrypt(privateKey, resultBytes);

System.out.println("明文是:" + msg);
System.out.println("加密后是:" + new String(resultBytes));
System.out.println("解密后是:" + new String(decBytes));
}

}


[b]2. DSA [/b]
Digital Signature Algorithm (DSA)是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。(感觉有点复杂,没有附代码)
详见[url]http://63938525.iteye.com/blog/1051565[/url]

[b](三)、题外话 MySQL加密解密函数[/b]
MySQL有两个函数来支持这种类型的加密,分别叫做ENCODE()和DECODE()。
下面是一个简单的实例:


mysql> INSERT INTO users (username,password) VALUES ('joe',ENCODE('guessme','abr'));

Query OK, 1 row affected (0.14 sec)


其中,Joe的密码是guessme,它通过密钥abracadabra被加密。要注意的是,加密完的结果是一个二进制字符串,如下所示:

提示:虽然ENCODE()和DECODE()这两个函数能够满足大多数的要求,但是有的时候您希望使用强度更高的加密手段。在这种情况下,您可以使用AES_ENCRYPT()和AES_DECRYPT()函数,它们的工作方式是相同的,但是加密强度更高。


单向加密与双向加密不同,一旦数据被加密就没有办法颠倒这一过程。因此密码的验证包括对用户输入内容的重新加密,并将它与保存的密文进行比对,看是否匹配。一种简单的单向加密方式是MD5校验码。MySQL的MD5()函数会为您的数据创建一个“指纹”并将它保存起来,供验证测试使用。下面就是如何使用它的一个简单例子:


mysql> INSERT INTO users (username,password) VALUES ('joe',MD5('guessme'));

Query OK, 1 row affected (0.00 sec)



或者,您考虑一下使用ENCRYPT()函数,它使用系统底层的crypt()系统调用来完成加密。这个函数有两个参数:一个是要被加密的字符串,另一个是双(或者多)字符的“salt”。它然后会用salt加密字符串;这个salt然后可以被用来再次加密用户输入的内容,并将它与先前加密的字符串进行比对。下面一个例子说明了如何使用它:


mysql> INSERT INTO users (username,password) VALUES('joe', ENCRYPT('guessme','ab'));

Query OK, 1 row affected (0.00 sec)



提示:ENCRYPT()只能用在UNIX、LINIX系统上,因为它需要用到底层的crypt()库。

[b]二、单向加密(信息摘要)[/b]
Java一般需要获取对象MessageDigest来实现单项加密(信息摘要)。
[b]1. MD5[/b] 即Message-Digest Algorithm 5(信息-摘要算法 5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、MD3和MD4。MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。
除了MD5以外,其中比较有名的还有sha-1、RIPEMD以及Haval等

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class EncrypMD5 {

public byte[] eccrypt(String info) throws NoSuchAlgorithmException{
//根据MD5算法生成MessageDigest对象
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] srcBytes = info.getBytes();
//使用srcBytes更新摘要
md5.update(srcBytes);
//完成哈希计算,得到result
byte[] resultBytes = md5.digest();
return resultBytes;
}


public static void main(String args[]) throws NoSuchAlgorithmException{
String msg = "郭XX-精品相声技术";
EncrypMD5 md5 = new EncrypMD5();
byte[] resultBytes = md5.eccrypt(msg);

System.out.println("密文是:" + new String(resultBytes));
System.out.println("明文是:" + msg);
}

}


[b]2. SHA[/b] 是一种数据加密算法,该算法经过加密专家多年来的发展和改进已日益完善,现在已成为公认的最安全的散列算法之一,并被广泛使用。该算法的思想是接收一段明文,然后以一种不可逆的方式将它转换成一段(通常更小)密文,也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输出序列即散列值(也称为信息摘要或信息认证代码)的过程。散列函数值可以说时对明文的一种“指纹”或是“摘要”所以对散列值的数字签名就可以视为对此明文的数字签名。


import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class EncrypSHA {

public byte[] eccrypt(String info) throws NoSuchAlgorithmException{
MessageDigest md5 = MessageDigest.getInstance("SHA");
byte[] srcBytes = info.getBytes();
//使用srcBytes更新摘要
md5.update(srcBytes);
//完成哈希计算,得到result
byte[] resultBytes = md5.digest();
return resultBytes;
}

/**
* @param args
* @throws NoSuchAlgorithmException
*/
public static void main(String[] args) throws NoSuchAlgorithmException {
String msg = "郭XX-精品相声技术";
EncrypSHA sha = new EncrypSHA();
byte[] resultBytes = sha.eccrypt(msg);
System.out.println("明文是:" + msg);
System.out.println("密文是:" + new String(resultBytes));

}

}


附件中是以上几种的源代码,附带额外的两种使用方式。

增加一种关于文件的哈希算法源代码:

import java.io.FileInputStream;
import java.io.InputStream;
import java.security.MessageDigest;

public class FileHashUtil {

public static final char[] hexChar = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
public static final String[] hashTypes = new String[] { "MD2", "MD5", "SHA1", "SHA-256", "SHA-384", "SHA-512" };

public void MD5File(String fileName) throws Exception{
//String fileName = args[0];
System.out.println("需要获取hash的文件为: " + fileName);
java.util.List<MessageDigest> mds = new java.util.ArrayList<MessageDigest>();
for (String hashType : hashTypes) {
MessageDigest md = MessageDigest.getInstance(hashType);
mds.add(md);
}
InputStream fis = null;
try {
fis = new FileInputStream(fileName);
byte[] buffer = new byte[1024];
int numRead = 0;
while ((numRead = fis.read(buffer)) > 0) {
for (MessageDigest md : mds) {
md.update(buffer, 0, numRead);
}
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (fis != null) {
fis.close();
}
}
for (MessageDigest md : mds) {
System.out.println(md.getAlgorithm() + " == " + toHexString(md.digest()));
}
}


public static void main(String[] args) throws Exception {
String[] fileName = new String[] {"D:/hapfish/ShellFolder.java","D:/hapfish/ShellFolder - 副本.java",
"E:/ShellFolder - 副本.java","E:/ShellFolder.txt","D:/hapfish/ShellFolder.jpg",
"E:/ShellFolder增加字符.txt","D:/hapfish/birosoft.jar"};
FileHashUtil files = new FileHashUtil();
for(int i=0;i<fileName.length;i++){
files.MD5File(fileName[i]);
}


}

public static String toHexString(byte[] b) {
StringBuilder sb = new StringBuilder(b.length * 2);
for (int i = 0; i < b.length; i++) {
sb.append(hexChar[(b[i] & 0xf0) >>> 4]);
sb.append(hexChar[b[i] & 0x0f]);
}
return sb.toString();
}

}


运行说明

"D:/hapfish/ShellFolder.java",
"D:/hapfish/ShellFolder - 副本.java",
"E:/ShellFolder - 副本.java",
"E:/ShellFolder.txt",
"D:/hapfish/ShellFolder.jpg",
以上五个文件是同一文件经过复制、改扩展名的,最后计算哈希结果是一致的。

"E:/ShellFolder增加字符.txt" 增加了几个字符串,就不一样了

"D:/hapfish/birosoft.jar" 完全不相关的另外一个文件


运行结果:

需要获取hash的文件为: D:/hapfish/ShellFolder.java
MD2 == 3a755a99c5e407005cd45ebd856b4649
MD5 == 5d08d440fa911d1e418c69a90b83cd86
SHA1 == 522c8c4f4ff1dd669e251c2ab854c3033a51ca63
SHA-256 == d1feb0c73c10a759e88bd240cb9d56d0598b4ff83a0704c6679f7ba12f6c4d99
SHA-384 == 8f8c9da4cd7241c58af3c52b49199033f2dcf3d67f421753999f87511618d9ea2d738e8c16b9b68a7572d06108ff10f6
SHA-512 == 4711579daee3ddacbaea189310348956cb43bcaaf0099f3be047b06f16c1a20a6b71ee3a4ee018128d647e9f2ef0d644747672238e49a8da3d0cd26dfe597458
需要获取hash的文件为: D:/hapfish/ShellFolder - 副本.java
MD2 == 3a755a99c5e407005cd45ebd856b4649
MD5 == 5d08d440fa911d1e418c69a90b83cd86
SHA1 == 522c8c4f4ff1dd669e251c2ab854c3033a51ca63
SHA-256 == d1feb0c73c10a759e88bd240cb9d56d0598b4ff83a0704c6679f7ba12f6c4d99
SHA-384 == 8f8c9da4cd7241c58af3c52b49199033f2dcf3d67f421753999f87511618d9ea2d738e8c16b9b68a7572d06108ff10f6
SHA-512 == 4711579daee3ddacbaea189310348956cb43bcaaf0099f3be047b06f16c1a20a6b71ee3a4ee018128d647e9f2ef0d644747672238e49a8da3d0cd26dfe597458
需要获取hash的文件为: E:/ShellFolder - 副本.java
MD2 == 3a755a99c5e407005cd45ebd856b4649
MD5 == 5d08d440fa911d1e418c69a90b83cd86
SHA1 == 522c8c4f4ff1dd669e251c2ab854c3033a51ca63
SHA-256 == d1feb0c73c10a759e88bd240cb9d56d0598b4ff83a0704c6679f7ba12f6c4d99
SHA-384 == 8f8c9da4cd7241c58af3c52b49199033f2dcf3d67f421753999f87511618d9ea2d738e8c16b9b68a7572d06108ff10f6
SHA-512 == 4711579daee3ddacbaea189310348956cb43bcaaf0099f3be047b06f16c1a20a6b71ee3a4ee018128d647e9f2ef0d644747672238e49a8da3d0cd26dfe597458
需要获取hash的文件为: E:/ShellFolder.txt
MD2 == 3a755a99c5e407005cd45ebd856b4649
MD5 == 5d08d440fa911d1e418c69a90b83cd86
SHA1 == 522c8c4f4ff1dd669e251c2ab854c3033a51ca63
SHA-256 == d1feb0c73c10a759e88bd240cb9d56d0598b4ff83a0704c6679f7ba12f6c4d99
SHA-384 == 8f8c9da4cd7241c58af3c52b49199033f2dcf3d67f421753999f87511618d9ea2d738e8c16b9b68a7572d06108ff10f6
SHA-512 == 4711579daee3ddacbaea189310348956cb43bcaaf0099f3be047b06f16c1a20a6b71ee3a4ee018128d647e9f2ef0d644747672238e49a8da3d0cd26dfe597458
需要获取hash的文件为: D:/hapfish/ShellFolder.jpg
MD2 == 3a755a99c5e407005cd45ebd856b4649
MD5 == 5d08d440fa911d1e418c69a90b83cd86
SHA1 == 522c8c4f4ff1dd669e251c2ab854c3033a51ca63
SHA-256 == d1feb0c73c10a759e88bd240cb9d56d0598b4ff83a0704c6679f7ba12f6c4d99
SHA-384 == 8f8c9da4cd7241c58af3c52b49199033f2dcf3d67f421753999f87511618d9ea2d738e8c16b9b68a7572d06108ff10f6
SHA-512 == 4711579daee3ddacbaea189310348956cb43bcaaf0099f3be047b06f16c1a20a6b71ee3a4ee018128d647e9f2ef0d644747672238e49a8da3d0cd26dfe597458
需要获取hash的文件为: E:/ShellFolder增加字符.txt
MD2 == f2717c24c6c0e110457bd17221c9ca6c
MD5 == c49e353a7c4c26bd7ccb5e90917c230f
SHA1 == 477c8a9e465bfaa4be42d35c032a17f7e6b42b97
SHA-256 == 9fa18adaf242ebcdc6563922d84c2a163c82e1a24db2eb2b73978ed1f354a8a3
SHA-384 == 4eee8f8e6d64d21c15dc01fa049f4d12a3b8e1d94d87763fe0bea75ab5ea8432fa8251289ece45ee39fe3d36b3c3020c
SHA-512 == e852ec0ff77250be497389d2f5a1818c18bb66106b9905c4ee26fe0d256eb3b77e0ce9a28a84e4b67e4332ba37ec3aa7518148e3a682318c0fc34c391f45c201
需要获取hash的文件为: D:/hapfish/birosoft.jar
MD2 == 38c5e1404718916dec59c33cafc909b3
MD5 == dc3e2cc4fb3949cf3660e0f5f8c3fba3
SHA1 == cde3dc25498afc5a563af0bb0eb54dc45f71bb28
SHA-256 == adf6a961c70c6ea677dff066fc5d896fb0beb4dd442ca0eb619ae1d1b04291e5
SHA-384 == fe7c6b754893c53ebd82bb53703fb5cc32115c9a38f98072f73def90729b271ee3c5c78e258bd9ff5ee5476193c2178b
SHA-512 == a15376f327256a6e049dfbdc5c2ad3a98bffccc6fa92ee01ff53db6b04471ca0f45ca28f76ff4a6911b57825afa046671299141f2499d71f1dac618c92385491



最后,把运行结果贴出来有点占空间,主要为了说明表述自己的猜想。一般来说同一哈希算法对同一文件(镜像、扩展名被修改)所产生的结果应该是一致的。

因此有个猜想,在baidu文库、腾讯的群共享上传时,先会判断是否有相同文件,从某种可能上来说也采用了对文件的哈希算法,毕竟从本地运算一个哈希算法后获得的数值要比把整个文件传过去比较实惠得多。而且字符串的比较也是很方便的。

对于某一种哈希算法,存在一种可能:就是两个不同的文件,计算出来的哈希值可能是一样的。当然为了保险,可以用两种甚至更多的哈希算法,只有在每种算法获得的哈希值都相同时,才能判断是同一个文件。
如果我们也对用户上传的文件进行哈希计算的话,就可以节省资源,同样的文件按理说可以减少上传次数……
Java中常用加密/解密方法详解 本文主要介绍了Java中常用加密/解密方法。具有很好的参考价值,下面跟着小编一起来看下吧 立即下载

相关推荐

labview的TDMS文件读写

本文先介绍TDMS概念和文件结构,然后介绍VI如何使用,最后分析一个labview的自带范例

观则明的博客 1万+

JAVA各种加密与解密方式

信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值。//信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值。/*** @param input 明文* @param algorithm 算法 MD5 | sha-1 SHA-256 |* @return 密文 Base64 & Hex*///0xff是16进制数,这个刚好8位都是1的二进制数,而且转成int类型的时候,高位会补0//只取得低八位。

【有梦想的菜】的博客 1万+

大样本EEG公共数据集汇总

描述: OpenNeuro平台包含多个认知障碍相关的EEG数据集,例如针对轻度认知障碍(MCI)或阿尔茨海默病(AD)的研究。描述: 天普大学医院EEG语料库包含大量临床EEG记录,可通过元数据筛选出与认知障碍相关的片段(如诊断标签包含dementia或MCI)。描述: ADNI主要提供多模态神经影像数据(MRI/PET),但部分合作研究整合了EEG数据。样本量: 部分数据集包含100+被试(例如结合MRI与EEG的多模态数据)。样本量:30,000+ EEG记录(持续更新,全球最大临床EEG数据库)。

谁人打的太极拳的博客 1759

如何解决使用Java17无法访问的com.sun.Crypto.Provide

在我的一个项目类中,我有行Security.addProvider(new com.sun.crypto.provider.SunJCE());本文介绍了如何解决使用Java17无法访问的com.sun.Crypto.Provider.SunJCE类型(&Q;这篇关于如何解决使用Java11无法访问的com.sun.Crypto.Provider.SunJCE类型(&Q;java.security.Security.getProviders()返回包括SunJCE在内的所有提供程序。

weixin_42396189的博客 2677

在windows上,在WSL 2(windows subsystem linux) 里一步步安装vLLM

本文介绍了在Windows系统上通过WSL2配置GPU加速的AI开发环境的完整流程。主要包括四个步骤: 1)安装WSL2并配置Ubuntu环境; 2)安装NVIDIA驱动和CUDA工具包; 3)搭建Python虚拟环境并安装vLLM; 4)验证环境并启动AI模型服务。

2601_96126911的博客 421

概率整形 Peobabilistic Shaping PS 第一节

概率整形概述 概率整形(Peobabilistic Shaping, PS)是一种针对于调制格式的优化技术,它为光通信通信提供了非常高的灵活性,但不会增加系统复杂性。尤其是光通信中的非线性问题会限制功率,使得PS就像为光通信量身定做的一样。 PS技术能够在不增加发送功率的前提下,获得高频谱效率和传输容量。2016年在使用PS技术的实验中实现了6600km单模光纤的65Tbit/s数据的传输。 到目前位置PS技术的研究主要集中在具有相干检测的单载波光纤传输。 概率整形的基本原理 概率整形技术就是通过在编码前

Explore_OuO的博客 8126

Java11解决Maven打包编译找不到“com.sun.crypto.provider.SunJCE 的问题”?

jdk11 com.sun.crypto.provider.SunJCE() 加密字符串安全问题

weixin_43862923的博客 4978

机器学习-02 模型的评估与选择

2.1 误差与过拟合 我们将学习器对样本的实际预测结果与样本的真实值之间的差异成为:误差(error)。定义: 在训练集上的误差称为训练误差(training error)或经验误差(empirical error)。 在测试集上的误差称为测试误差(test error)。 学习器在所有新样本上的误差称为泛化误差(generalization error)。 显然,我们希望得到的是在新样本上表现得很好的学习器,即泛化误差小的学习器。因此,我们应该让学习器尽可能地从训练集中学出普适性的“一般特征”,这

一个小白 1703

加密系列 | Java中常用的加密方法(JDK)

加密,是以某种特殊的算法改变原有的信息数据,使得未授权的用户即使获得了已加密的信息,但因不知解密的方法,仍然无法了解信息的内容。大体上分为双向加密和单向加密 ,而双向加密又分为对称加密和非对称加密 (有些资料将加密直接分为对称加密和非对称加密)。 双向加密大体意思就是明文加密后形成密文,可以通过算法还原成明文。而单向加密只是对信息进行了摘要计算,不能通过算法生成明文,单向加密从严格意思上说不能算是...

挖坑埋你 1484

【电机驱动与运动控制】期末重点问题集合

问题1 梯形曲线和S形曲线各自的特点和区别,比较梯形和S形曲线位置、速度、加速度、加加速度的区别。 问题2 总惯量的计算包含哪几个部分? 哪几个部分需要进行折算? 在齿轮箱的输出侧(2号轴)总惯量需要折算到齿轮箱的输入侧(1号轴) 为什么需要折算? 齿轮箱比的存在使2号轴的转速和电机的转速不同 问题3 指出每个部分的名称。 每个部分的功能。 主磁极的励磁绕组:绝大部分直流电机都是由励磁绕组通以直流电建立主磁场; - 电枢铁心:在两个主磁极内表面之间,由硅钢片叠成的圆

【人工智障 | 计算鸡视觉 | 机器孩】 5703

2024年11月架构设计师综合知识真题回顾,附参考答案、解析及所涉知识点(一)

软考高级考试包含三个科目:信息系统综合知识、系统架构设计案例分析和系统架构设计论文。考试形式为机考。本文主要回顾2024年下半年(2024-11-10)系统架构设计师考试上午综合知识科目的选择题,同时附带参考答案、解析和所涉知识点。由于机考时题目顺序是打乱的,本文题目所标序号只为区分不代表实际顺序。综合知识。

一几文的编程学习笔记。 9278

加密系列—Java中常用的加密方法(JDK)

加密,是以某种特殊的算法改变原有的信息数据,使得未授权的用户即使获得了已加密的信息,但因不知解密的方法,仍然无法了解信息的内容。大体上分为双向加密和单向加密 ,而双向加密又分为对称加密和非对称加密 (有些资料将加密直接分为对称加密和非对称加密)。   双向加密大体意思就是明文加密后形成密文,可以通过算法还原成明文。而单向加密只是对信息进行了摘要计算,不能通过算法生成明文,单向加密从严格意思上说不能算

此博客已停用,博文会逐渐转移到新地址,http://blog.youkuaiyun.com/liupeifeng3514 1047

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

[转]Java中常用的加密方法(JDK)

[转]Java中常用的加密方法(JDK) 2012-10-15阅读335 评论0 加密,是以某种特殊的算法改变原有的信息数据,使得未授权的用户即使获得了已加密的信息,但因不知解密的方法,仍然无法了解信息的内容。大体上分为双向加密和单向加密,而双向加密又分为对称加密和非对称加密(有些资料将加密直接分为对称加密和非对称加密)。  双向加密大体意思就是明文加密后形成密文,可以通过算法还

u011286208的专栏 945

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

上一篇: windows下oracle完全卸载
下一篇: oralce常用操作、查询语句(查看表空间)
hapfish
博客等级 码龄18年 3粉丝 7原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值