java 数字签名 例子_Java加密和数字签名

/**

*MessageDigestExample.java

*Copyright 2005-2-16

*/

import java.security.MessageDigest;

/**

*单一的消息摘要算法,不使用密码.可以用来对明文消息(如:密码)隐藏保存

*/

public class MessageDigestExample{

public static void main(String[] args) throws Exception{

if(args.length!=1){

System.err.println("Usage:java MessageDigestExample text");

System.exit(1);

}

byte[] plainText=args[0].getBytes("UTF8");

//使用getInstance("算法")来获得消息摘要,这里使用SHA-1的160位算法

MessageDigest messageDigest=MessageDigest.getInstance("SHA-1");

System.out.println("/n"+messageDigest.getProvider().getInfo());

//开始使用算法

messageDigest.update(plainText);

System.out.println("/nDigest:");

//输出算法运算结果

System.out.println(new String(messageDigest.digest(),"UTF8"));

}

}

还可以通过消息认证码来进行加密实现,javax.crypto.Mac提供了一个解决方案,有兴趣者可以参考相关API文档,本文只是简单介绍什么是摘要算法。

这里补充另一个运用消息摘要的方式加密的例子:

public class TestEncrypt {

public TestEncrypt() {

}

/**

* @param strSrc :strSrc is a string will be encrypted,

* @param encName : encName is the algorithm name will be used.

* encName dafault to "MD5"

* @return String

*/

public String Encrypt(String strSrc, String encName) {

MessageDigest md = null;

String strDes = null;

byte[] bt = strSrc.getBytes();

try {

if (encName == null || encName.equals("")) {

encName = "MD5";

}

md = MessageDigest.getInstance(encName);

md.update(bt);

strDes = bytes2Hex(md.digest()); //to HexString

}

catch (NoSuchAlgorithmException e) {

System.out.println("Invalid algorithm.");

return null;

}

return strDes;

}

public String bytes2Hex(byte[] bts) {

String des = "";

String tmp = null;

for (int i = 0; i < bts.length; i++) {

tmp = (Integer.toHexString(bts[i] & 0xFF));

if (tmp.length() == 1) {

des += "0";

}

des += tmp;

}

return des;

}

public static void main(String[]args) {

TestEncrypt te = new TestEncrypt();

String strSrc = "可以加密汉字.Oh,and english";

System.out.println("Source String:" + strSrc);

System.out.println("Encrypted String:");

System.out.println("Use Def:" + te.Encrypt(strSrc, null));

System.out.println("Use MD5:" + te.Encrypt(strSrc, "MD5"));

System.out.println("Use SHA:" + te.Encrypt(strSrc, "SHA-1"));

System.out.println("Use SHA-256:" + te.Encrypt(strSrc, "SHA-256"));

}

}

另外,在javawebparts中的 RequestHelpers里的generateGUID方法也涉及到了MD5的方法,代码如下:

public static String generateGUID(HttpServletRequest request) {

String out = "";

try {

// Construct a string that is comprised of:

// Remote IP Address + Host IP Address + Date (yyyyMMdd) +

// Time (hhmmssSSa) + Requested Path + Session ID +

// HashCode Of ParameterMap

StringBuffer sb = new StringBuffer(1024);

sb.append(request.getRemoteAddr());

InetAddress ia = InetAddress.getLocalHost();

sb.append(ia.getHostAddress());

sb.append(new SimpleDateFormat("yyyyMMddhhmmssSSa").format(new Date()));

String path = request.getServletPath();

String pathInfo = request.getPathInfo();

if (pathInfo != null) {

path += pathInfo;

}

sb.append(path);

sb.append(request.getSession(false));

sb.append(request.getParameterMap().hashCode());

String str = sb.toString();

// Now encode the string using an MD5 encryption algorithm.

MessageDigest md = MessageDigest.getInstance("md5");

md.update(str.getBytes());

byte[] digest = md.digest();

StringBuffer hexStr = new StringBuffer(1024);

for (int i = 0; i < digest.length; i++) {

str = Integer.toHexString(0xFF & digest[i]);

if (str.length() < 2) {

str = "0" + str;

}

hexStr.append(str);

}

out = hexStr.toString();

} catch (NoSuchAlgorithmException nsae) {

log.error(nsae);

} catch (UnknownHostException uhe) {

log.error(uhe);

}

// Return the encrypted string. It should be unique based on the

// components that comprise the plain text string, and should always be

// 32 characters thanks to the MD5 algorithm.

return out;

} // End generateGUID().

2)私钥加密:

消息摘要只能检查消息的完整性,但是单向的,对明文消息并不能加密,要加密明文的消息的话,就要使用其他的算法,要确保机密性,我们需要使用私钥密码术来交换私有消息。

这种最好理解,使用对称算法。比如:A用一个密钥对一个文件加密,而B读取这个文件的话,则需要和A一样的密钥,双方共享一个私钥(而在web环境下,私钥在传递时容易被侦听):

使用私钥加密的话,首先需要一个密钥,可用javax.crypto.KeyGenerator产生一个密钥(java.security.Key), 然后传递给一个加密工具(javax.crypto.Cipher),该工具再使用相应的算法来进行加密,主要对称算法有:DES(实际密钥只用到56 位),AES(支持三种密钥长度:128、192、256位),通常首先128位,其他的还有DESede等,jdk1.5种也提供了对对称算法的支持,以下例子使用AES算法来加密:

/**

*PrivateExmaple.java

*Copyright 2005-2-16

*/

import javax.crypto.Cipher;

import javax.crypto.KeyGenerator;

import java.security.Key;

/**

*私鈅加密,保证消息机密性

*/

public class PrivateExample{

public static void main(String[] args) throws Exception{

if(args.length!=1){

System.err.println("Usage:java PrivateExample ");

System.exit(1);

}

byte[] plainText=args[0].getBytes("UTF8");

//通过KeyGenerator形成一个key

System.out.println("/nStart generate AES key");

KeyGenerator keyGen=KeyGenerator.getInstance("AES");

keyGen.init(128);

Key key=keyGen.generateKey();

System.out.println("Finish generating DES key");

//获得一个私鈅加密类Cipher,ECB是加密方式,PKCS5Padding是填充方法

Cipher cipher=Cipher.getInstance("AES/ECB/PKCS5Padding");

System.out.println("/n"+cipher.getProvider().getInfo());

//使用私鈅加密

System.out.println("/nStart encryption:");

cipher.init(Cipher.ENCRYPT_MODE,key);

byte[] cipherText=cipher.doFinal(plainText);

System.out.println("Finish encryption:");

System.out.println(new String(cipherText,"UTF8"));

System.out.println("/nStart decryption:");

cipher.init(Cipher.DECRYPT_MODE,key);

byte[] newPlainText=cipher.doFinal(cipherText);

System.out.println("Finish decryption:");

System.out.println(new String(newPlainText,"UTF8"));

}

}

3)公钥加密:

上面提到,私钥加密需要一个共享的密钥,那么如何传递密钥呢?web环境下,直接传递的话很容易被侦听到,幸好有了公钥加密的出现。公钥加密也叫不对称加密,不对称算法使用一对密钥对,一个公钥,一个私钥,使用公钥加密的数据,只有私钥能解开(可用于加密);同时,使用私钥加密的数据,只有公钥能解开(签名)。但是速度很慢(比私钥加密慢100到1000倍),公钥的主要算法有RSA,还包括Blowfish,Diffie-Helman等, jdk1.5种提供了对RSA的支持,是一个改进的地方:

/**

*PublicExample.java

*Copyright 2005-2-16

*/

import java.security.Key;

import javax.crypto.Cipher;

import java.security.KeyPairGenerator;

import java.security.KeyPair;

/**

*一个简单的公鈅加密例子,Cipher类使用KeyPairGenerator生成的公鈅和私鈅

*/

public class PublicExample{

public static void main(String[] args) throws Exception{

if(args.length!=1){

System.err.println("Usage:java PublicExample ");

System.exit(1);

}

byte[] plainText=args[0].getBytes("UTF8");

//构成一个RSA密钥

System.out.println("/nStart generating RSA key");

KeyPairGenerator keyGen=KeyPairGenerator.getInstance("RSA");

keyGen.initialize(1024);

KeyPair key=keyGen.generateKeyPair();

System.out.println("Finish generating RSA key");

//获得一个RSA的Cipher类,使用公鈅加密

Cipher cipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");

System.out.println("/n"+cipher.getProvider().getInfo());

System.out.println("/nStart encryption");

cipher.init(Cipher.ENCRYPT_MODE,key.getPublic());

byte[] cipherText=cipher.doFinal(plainText);

System.out.println("Finish encryption:");

System.out.println(new String(cipherText,"UTF8"));

//使用私鈅解密

System.out.println("/nStart decryption");

cipher.init(Cipher.DECRYPT_MODE,key.getPrivate());

byte[] newPlainText=cipher.doFinal(cipherText);

System.out.println("Finish decryption:");

System.out.println(new String(newPlainText,"UTF8"));

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值