1. 密碼學簡介 – 加密與解密
加密是一個將欲加密的資料用一些數學運算轉成一團令人看不懂的東西的過程; 解密則是將加密文轉換回原始文字的過程。這個過程中,扮演原始文字與加密文字之間轉換的數學演算法稱為Cipher。
圖1 Cipher的運作
現代的Cipher多半會用Key來加密與解密資料。所謂Key是指一個機密值,我們可將它視為一通行密碼。加密文字必需使用對映的Key才能解密為原始文字。
A. 對稱型Cipher
對稱型Cipher在傳送端與接收端所用的Key是一樣的,如圖2所示,對稱型Cipher又叫Private Key Cipher,因為Key 的值只有傳送端和接收端知道。如果有第三者知道了Private Key值,也就能解開加密的資料。
圖2 對稱型Cipher的運作
B. 非對稱型Cipher
非對稱型的Cipher又叫Public Key Cipher,Cipher除了Private Key外,還會引進一可以隨意散發的Public Key。被 Public Key加密的資料只有相對映的Private Key可以解開,同樣的被Private Key加密的資料也只有相對映的Public Key 可以解開。如圖3所示,顯示了非對稱型Cipher的運作過程。
圖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.");
}
}
}
分享到:
相关推荐
这是我关于密码学的笔记, 只讲各种加密算法到底是什么, 应当如何使用, 而不去讲学术的内容. 所以, 这是精华中的精华, 适合绝大多数想对密码学进行快速学习和完整了解的程序员. 我使用的是markdown形式做笔记, 树状...
NULL 博文链接:https://ye-liang.iteye.com/blog/2002980
JAVA中一些基础的密码学知识,对基本的加密解密方法和算法有较详细的解释
Java密码学架构中利用对称密钥加解密的一个小Demo。
Tutorialspoint Java 密码学教程.epub
Java密码学实验室指南.zip
Java密码学API注解及模板生成框架
Tutorialspoint Java 密码学教程、YAML、Vim、Python 文本处理、并发编程、Pycharm 教程
密码学中的DES算法的java代码 写得比较难看 多见谅
随着黑客攻击的增长趋势,每个人都应该为其不同的帐户创建不同且复杂的...要整合这一点,您需要学习密码学和Java密码学体系结构的基础知识。 此项目是一个 Java 控制台应用程序,用于生成随机密码并执行密码强度检查。
java编程密码学java编程密码学java编程密码学java编程密码学java编程密码学java编程密码学java编程密码学java编程密码学java编程密码学java编程密码学java编程密码学java编程密码学java编程密码学
Java 密码学和安全课程 日程 介绍 Java 中的密码学 介绍。 加密服务。 供应商。 引擎类 加密密钥。 加密。 信息摘要。 电子签名 使用 Java 的 PKI 基础架构 证书和认证机构。 X.509 证书 证书覆盖列表 (crls) ...
该资源内项目源码是个人的课程设计作业,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到94.5分,放心下载使用! 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!...
这是我的密码学项目,比较简单,实现了DES,AES,RSA。拿java做了简单的可视化界面。代码也是拿java实现的。没有调用java的security包。注释不怎么样。但是可以直接运行。略微有点小bug。
密码学实验 ,序列密码, java
NULL 博文链接:https://ye-liang.iteye.com/blog/2002828
密码学试验DES的源程序代码,是一个.cpp文件
自己总结的java安全密码学的笔记,绘制了详细的思维导图,每个思维导图中均有详细的博文解释,方便大家学习和理解,免费分享给大家。适合java的爱好者和学习者
对Android/Java密码学SDK的组成和实现原理进行了总结性的介绍。
经典密码学与现代密码学,清晰完整版,设计密码的人都是神