QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1956|回复: 0

Java中的加密和DSA数字签名

[复制链接]
发表于 2004-6-25 12:14:46 | 显示全部楼层 |阅读模式
Java中的加密和DSA数字签名

Bromon原创 请尊重版权

一、单向加密(MD5和SHA-1)

单向加密通常用于消息摘要,具体算法可以阅读java.security.*的源代码获得。经过封装之后可以使用简单的静态方法来实现,Look:

[code:1]package org.bromon;
public class MD5Encoder
{
public static void main(String args[])
{
  String info=args[0];
  try
  {
   //选择MD5加密算法
   java.security.MessageDigest alg=
java.security.MessageDigest.getInstance("MD5");

   //选择SHA-1加密算法
   //java.security.MessageDigest alg=
java.security.MessageDigest.getInstance("SHA-1");

   alg.update(info.getBytes());
   byte[] digesta=alg.digest();
   String result="";
   for(int i=0;i<digesta.length;i++)
   {
    int m=digesta[i];
    if(m<0)
    {
     m+=256;//如果是负数就取模
    }

    result=result+Integer.toString(m,16).toUpperCase()+"";//转换为大写字符
   }
   System.out.println(result);
  }catch(Exception e)
  {
   System.out.println(e);
  }
}
}
  [/code:1]

编译:javac –d . MD5Encoder.java
运行:java org.bromon.MD5Encoder someData

DES作为单钥加密的代表,目前好象仍然处于五角大楼出口限制的列表中!?

二、非对称加密DSA数字签名

通过使用密钥对来实现。根据非对称加密的原理,分发公钥并用其加密,私钥保密,用于解密。而DSA的数字签名则是利用私钥加密,公钥解密,用以保证不可否认性和完整性。以DSA数字签名为例:

首先需要生成一对密钥:

[code:1]package org.bromon;
import java.io.*;
import java.security.*;

public class DSAGenerateKeyPair
{
public static void main(String args[])
{
  try
  {
   java.security.KeyPairGenerator keygen=
java.security.KeyPairGenerator.getInstance("DSA");

   SecureRandom sr=new SecureRandom();
   sr.setSeed("123".getBytes());//密钥种子
   keygen.initialize(512,sr);
   
   KeyPair keys=keygen.generateKeyPair();
   PublicKey pubkey=keys.getPublic();
   PrivateKey prikey=keys.getPrivate();

   //将生成的密钥对序列化到文件
   ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("prikey.dat"));
   out.writeObject(prikey);
   out.close();
   
   out=new ObjectOutputStream(new FileOutputStream("pubkey.dat"));
   out.writeObject(pubkey);
   out.close();
  }catch(Exception e)
  {
   System.out.println(e);
  }
  
}
}[/code:1]

运行之后会在当前目录生成两个.dat文件。

然后可以使用私钥对数据签名:

[code:1]package org.bromon;
import java.io.*;
import java.security.*;

public class DSASigner
{
public static void main(String args[])
{
  String s="需要加密的内容";
  try
  {
   //导入私钥
   ObjectInputStream in=new ObjectInputStream(new FileInputStream("prikey.dat"));
   PrivateKey prikey=(PrivateKey)in.readObject();
   in.close();
   
   //对数据签名
   Signature signature=Signature.getInstance("DSA");
   signature.initSign(prikey);
   signature.update(s.getBytes());
   byte[] signed=signature.sign();
   
   //将签名后的数据写入文件
   ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("info.dat"));
   out.writeObject(s);
   out.writeObject(signed);
   out.close();
  }catch(Exception e)
  {
   System.out.println(e);
  }
  
}

}[/code:1]

运行之后在当前路径产生一个加密后的文件,将此文件和公钥一起分发给接收者。

下面是使用公钥验证签名是否正常:

[code:1]package org.bromon;
import java.security.*;
import java.io.*;

public class DSAChecker
{
public static void main(String args[])
{
  try
  {
   //导入公钥
   ObjectInputStream in=new ObjectInputStream(new FileInputStream("pubkey.dat"));
   PublicKey pubkey=(PublicKey)in.readObject();
   in.close();
   
   //导入需要读取的文件
   in=new ObjectInputStream(new FileInputStream("info.dat"));
   String s=(String)in.readObject();
   byte[] signed=(byte[])in.readObject();
   in.close();
   
   //验证密钥对
   Signature signCheck=Signature.getInstance("DSA");
   signCheck.initVerify(pubkey);
   signCheck.update(s.getBytes());
   if(signCheck.verify(signed))
   {
    System.out.println(s);
   }else{
    System.out.println("无阅读权限");
   }
  }catch(Exception e)
  {
   System.out.println(e);
  }
  
}

}[/code:1]
运行之后如果密钥匹配无误,会显示加密的内容。如果公钥格式被破坏,会抛出异常。

Java有非常庞大的加密框架,各种加密和签名种类极多,OReilly - Java Cryptography中有详细介绍。不过一些包在中国无法得到。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-5-5 13:57 , Processed in 0.105776 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表