1. 密码学简介 – 加密与解密
加密是一个将欲加密的资料用一些数学运算转成一团令人看不懂的东西的过程 ; 解密则是将加密文转换回原始文字的过程。这个过程中,扮演原始文字与加密文字之间转换的数学算法称为 Cipher 。
现代的 Cipher 多半会用 Key 来加密与解密资料。所谓 Key 是指一个机密值,我们可将它视为一通行密码。加密文字必需使用对映的 Key 才能解密为原始文字。
A. 对称型 Cipher
对称型 Cipher 在传送端与接收端所用的 Key 是一样的, 对称型 Cipher 又叫 Private Key Cipher ,因为 Key 的值只有传送端和接收端知道。如果有第三者知道了 Private Key 值,也就能解开加密的资料。
B. 非对称型 Cipher
非对称型的 Cipher 又叫 Public Key Cipher , Cipher 除了 Private Key 外,还会引进一可以随意散发的 Public Key 。被 Public Key 加密的资料只有相对映的 Private Key 可以解开,同样的被 Private Key 加密的资料也只有相对映的 Public Key 可以解开。
C. 讯息摘要 (Message Digest)
讯息摘要是从一组输入资料计算所得的一个特别数字,其原理运作就如 hash function 一般。在密码学的运用里,一般是用来验证资料是否被窜改。
2. JCE 下载
因为美国法规的限制, Sun 在 JDK 里只提供了少数的加密方法,其余大部份则只在 SunJCE 里提供,而且 SunJCE 的 API 限制只有美国、加拿大地区可以下载。表 1 为 Sun 及 SunJCE 分别支持的加密算法。
|
名称
|
型别
|
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: java PwdDES -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的组成和实现原理进行了总结性的介绍。
经典密码学与现代密码学,清晰完整版,设计密码的人都是神