java 密碼學[轉]

原创 2004年10月14日 15:47:00

Java密碼學

(史帝芬, idealist@gcn.net.tw)


1. 密碼學簡介 – 加密與解密
加密是一個將欲加密的資料用一些數學運算轉成一團令人看不懂的東西的過程; 解密則是將加密文轉換回原始文字的過程。這個過程中,扮演原始文字與加密文字之間轉換的數學演算法稱為Cipher。

Java1.gif

圖1 Cipher的運作

現代的Cipher多半會用Key來加密與解密資料。所謂Key是指一個機密值,我們可將它視為一通行密碼。加密文字必需使用對映的Key才能解密為原始文字。
  A. 對稱型Cipher
對稱型Cipher在傳送端與接收端所用的Key是一樣的,如圖2所示,對稱型Cipher又叫Private Key Cipher,因為Key 的值只有傳送端和接收端知道。如果有第三者知道了Private Key值,也就能解開加密的資料。

Java2.gif

圖2 對稱型Cipher的運作

  B. 非對稱型Cipher
非對稱型的Cipher又叫Public Key Cipher,Cipher除了Private Key外,還會引進一可以隨意散發的Public Key。被 Public Key加密的資料只有相對映的Private Key可以解開,同樣的被Private Key加密的資料也只有相對映的Public Key 可以解開。如圖3所示,顯示了非對稱型Cipher的運作過程。

Java3.gif

圖3 非對稱型Cipher的運作

  C. 訊息摘要 (Message Digest)
訊息摘要是從一組輸入資料計算所得的一個特別數字,其原理運作就如hash function一般。在密碼學的運用裡,一般是用來驗證資料是否被竄改。

2. JCE下載
因為美國法規的限制,Sun在JDK裡只提供了少數的加密方法,其餘大部份則只在SunJCE裡提供,而且SunJCE的 API限制只有美國、加拿大地區可以下載。表1為Sun及SunJCE分別支援的加密演算法。

 <?XML:NAMESPACE PREFIX = O />

名稱

型別

Sun

MD5

訊息摘要

SHA-1

訊息摘要

DSA

簽章

SunJCE

HmacMD5

MAC

HmacSHA1

MAC

DES

對稱型Cipher

DESede

非對稱型Cipher

PBEWithMD5AndDES

對稱型Cipher

DH

Key的交換

表1 Sun及SunJCE支援的加密演算法

雖然美國法規有這樣的限定,但是在美國境外也已經有廠商實作出JCE,並且可以在網路上直接下載,表2就是下載網址的列表。

套件

網址

免費

JCE

http://java.sun.com/products/jdk/1.2/jce/

Cryptix

http://www.cryptix.org/

IAIK

http://wwwjce.iaik.tu-graz.ac.at/

表2 JCE軟體下載網址

3. JCE安裝
  • 解壓縮到JDK目錄下
  • Set ClassPath= C:/JDK/bin/cryptix-jce-api.jar;C:/JDK/bin/cryptix-jce-compat.jar;C:/JDK/bin/cryptix-jce-provider.jar …
  • 在JDK/lib/security/java.security中加入
    security.provider.1=sun.security.provider.Sun (原來就有的)
    security.provider.2=cryptix.jce.provider.Cryptix (加入)

4. 程式範例
在舉例之前,我先完成一個公用類別,用來將字串轉成十六進位表示法。
public class Msg {
 public static String toHexString(byte[] b) {
  StringBuffer hexString = new StringBuffer();
  String plainText;

  for (int i = 0; i < b.length; i++) {
   plainText = Integer.toHexString(0xFF & b[i]);
   if (plainText.length() < 2) {
    plainText = "0" + plainText;
   }
   hexString.append(plainText);
  }
  return hexString.toString();
 }
}

5. 訊息摘要 (message digest, 以SHA1為例)
  產生訊息摘要的步驟:
  • 呼叫getInstance取得MessageDigest實體
  • 呼叫update將資料餵給MessageDigest
  • 呼叫digest產生訊息摘要

import java.security.*;

public class SHA extends Object {
 public static void main(String[] args) throws Exception
 {
  MessageDigest md = MessageDigest.getInstance("SHA");
  md.update(args[0].getBytes());
  byte[] digest = md.digest();
  System.out.println(Msg.toHexString(digest));
 }
}

ps. 比較兩個訊息摘要是否相同時,可呼叫isEqual。

6. 訊息認證碼 (MAC, 以HmacSHA1為例)
訊息認證碼只是在產生訊息摘要的過程裡,加進一把key做為保護,目的是使訊息摘要更難被破解。
  產生訊息認證碼的步驟:
  • 利用密碼產生一把key
  • 呼叫getInstance取得Mac實體
  • 呼叫init,初始化Mac
  • 呼叫update餵資料給Mac
  • 呼叫doFinal產生訊息認證碼

import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;

public class MacSHA {
 public static void main(String[] args)
 {
  SecureRandom sr = new SecureRandom();
  byte[] keyBytes = new byte[20];
  sr.nextBytes(keyBytes);
  SecretKey key = new SecretKeySpec(keyBytes, "HmacSHA");

  try {
   Mac m = Mac.getInstance("HmacSHA");
   m.init(key);
   m.update(args[0].getBytes());
   byte[] mac = m.doFinal();
   System.out.println(Msg.toHexString(mac));
  }
  catch (Exception e) {
   System.out.println("Exception!!");
  }
 }
}


7. 加密與解密 (以DES為例)
這裡舉的加密/解密是屬對稱型Cipher; 在金融交易裡,常用對稱型Cipher來加/解密資料。
  加密/解密的步驟:
  • 利用密碼產生一把key
  • 呼叫getInstance產生一個Cipher物件
  • 呼叫init設定為加密或解密
  • 加密/解密

import java.io.*;
import java.security.*;
import javax.crypto.*;

public class PwdDES {
 public static final int kBufferSize = 8192;

 public static void main(String[] args) throws Exception {
  if (args.length < 4) {
   System.out.println("Usage: Cloak -e|-d passwd inputfile outputfile");
   return;
  }

  //Get or create key.

  Key key;

  KeyGenerator generator = KeyGenerator.getInstance("DES");
  generator.init(new SecureRandom(args[1].getBytes()));
  key = generator.generateKey();

  //Get a cipher object
  Cipher cipher = Cipher.getInstance("DES/ECB/PKCS#5");

  //Encrypt or decrypt
  if (args[0].indexOf("e") != -1)
   cipher.init(Cipher.ENCRYPT_MODE, key);
  else
   cipher.init(Cipher.DECRYPT_MODE, key);

  FileInputStream in = new FileInputStream(args[2]);
  FileOutputStream fileOut = new FileOutputStream(args[3]);
  CipherOutputStream out = new CipherOutputStream(fileOut, cipher);
  byte[] buffer = new byte[kBufferSize];
  int length;
  while ((length = in.read(buffer)) != -1)
   out.write(buffer, 0, length);
  in.close();
  out.close();
 }

}


8. 產生簽章與認證 (以DSA為例)
數位簽章常用在網路上做個人身份確認。
  產生簽章的步驟:
  • 呼叫getInstance取得一個Signature實體
  • 呼叫initSign初始化Signature
  • 呼叫sign產生簽章

  認證的步驟:
  • 呼叫getInstance取得一個Signature實體
  • 呼叫initVerify初始化Signature
  • 呼叫verify認證

Sample1: 產生Private/Public Key

import java.security.*;
import java.security.KeyPairGenerator;
import java.security.KeyPair;
import java.io.*;

public class KeyPair1 {

 public static void main(String[] args)
 {
  try {
   KeyPairGenerator genKeyPair = KeyPairGenerator.getInstance("DSA");
   genKeyPair.initialize(1024, new SecureRandom());
   KeyPair kpKey = genKeyPair.genKeyPair();
   PrivateKey prKey = kpKey.getPrivate();
   PublicKey puKey = kpKey.getPublic();

   ObjectOutputStream osPrivate = new ObjectOutputStream(new FileOutputStream("D://Private.Key"));
   ObjectOutputStream osPublic = new ObjectOutputStream(new FileOutputStream("D://Public.Key"));
   osPrivate.writeObject(prKey);
   osPublic.writeObject(puKey);

   osPrivate.close();
   osPublic.close();
  }
  catch (Exception e) {
   System.out.println("Error");
  }
 }
}

Sample2: 產生簽章與認證

import java.io.*;
import java.security.*;
import java.security.Signature;
import java.security.cert.*;

public class GenSign {

 public static void main(String[] args) throws Exception {
  String options = args[0];
  String messagefile = args[1];
  String signaturefile = args[2];

  Signature signature = Signature.getInstance("DSA");
  if (options.indexOf("s") != -1) {
   ObjectInputStream is = new ObjectInputStream(new FileInputStream("D://Private.key"));
   PrivateKey priKey = (PrivateKey) is.readObject();
   signature.initSign(priKey);
   is.close();
  }
  else {
   ObjectInputStream is = new ObjectInputStream(new FileInputStream("D://Public.key"));
   PublicKey pubKey = (PublicKey) is.readObject();
   signature.initVerify(pubKey);
   is.close();
  }

  FileInputStream in = new FileInputStream(messagefile);
  byte[] buffer = new byte[8192];
  int length;
  while ((length = in.read(buffer))!= -1)
   signature.update(buffer, 0, length);
  in.close();

  if (options.indexOf("s") != -1) {
   FileOutputStream out = new FileOutputStream(signaturefile);
   byte[] raw = signature.sign();
   out.write(raw);
   out.close();
  }
  else {
   FileInputStream sigIn = new FileInputStream(signaturefile);
   byte[] raw = new byte[sigIn.available()];
   sigIn.read(raw);
   sigIn.close();
   if (signature.verify(raw))
    System.out.println("The signature is good.");
   else
    System.out.println("The signature is bad.");
  }
 }
}

java 密碼學

http://www.jscode.cn/develop/v28537 java 密碼學   1. 密碼學簡介 – 加   密與解密 加密是一個將欲加密的資料用一些數學運算轉成一團令人看不...
  • guolong1983811
  • guolong1983811
  • 2012年11月23日 21:55
  • 258

Java密碼學[转]

原文地址:http://my.so-net.net.tw/idealist/Java/Cryptogram.html1. 密碼學簡介 – 加密與解密加密是一個將欲加密的資料用一些數學運算轉成一團令人看...
  • java_lk
  • java_lk
  • 2008年04月29日 11:19
  • 211

安装11g_rac配置等效性

ssh等效性配置
  • php521php
  • php521php
  • 2014年10月02日 16:20
  • 69773

轉載(學習網站)

http://www.gotapi.com/ 语言:英语 简介:HTML,CSS,XPATH,XSL,JAVASCRIPT等API的查询网站。http://www.w3schools.com/ 语言:...
  • kexijun20014
  • kexijun20014
  • 2009年08月12日 12:18
  • 221

C#接口的學習(轉)

什么是接口?其实,接口简单理解就是一种约定,使得实现接口的类或结构在形式上保持一致。个人觉得,使用接口可以使程序更加清晰和条理化,这就是接口的好处,但并不是所有的编程语言都支持接口,C#是支持接口的。...
  • nanqing
  • nanqing
  • 2008年06月28日 14:25
  • 596

自強不息,學習學習再學習

想起大學時印象很深的的一條循環語句 for (i=0,i ...... 現在,繼續這樣調動自己的學習興趣,不知道這樣寫出來能否運行呢? ...... DATA DIVISION. WORK...
  • rigolo
  • rigolo
  • 2012年06月09日 14:23
  • 138

Java中的上下转型

本文已搬家至【Java学习笔记】上转型与下转型
  • gnuhpc
  • gnuhpc
  • 2009年11月05日 19:20
  • 1135

JAVA学习指南

这一部分其实也算是今天的重点,这一部分用来回答很多群里的朋友所问过的问题,那就是LZ你是如何学习Java的,能不能给点建议?今天LZ是打算来点干货,因此咱们就不说一些学习方法和技巧了,直接来谈每个阶段...
  • dotaplayit
  • dotaplayit
  • 2016年04月22日 10:44
  • 1066

密碼學在 .NET 組件上的應用

密碼學在 .NET 組件上的應用作者:蔡學鏞2005 年 5 月本文章簡單地介紹了密碼學在.NET組件上的應用,內容包括了何謂 strong name、簽署的過程、簽署的查驗、Authenticode...
  • hhh21
  • hhh21
  • 2007年04月04日 16:15
  • 356

Mac OS X 密碼忘記沒關係!教你如何重置密碼

MAC 教 人生總有些時候頭腦突然失靈,信誓旦旦自以為會記得的密碼,想不到就這麼忘記了!這時候程式安裝會有困難,有很多需要管理者密碼才能執行的東西就這樣卡在那裡。 相信大家都已經用...
  • lcg0412
  • lcg0412
  • 2014年07月03日 10:55
  • 1175
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java 密碼學[轉]
举报原因:
原因补充:

(最多只允许输入30个字)