当前位置:文档之家› Java数字证书对文件加密解密签名校验签名

Java数字证书对文件加密解密签名校验签名

Java数字证书对文件加密解密签名校验签名
Java数字证书对文件加密解密签名校验签名

https://www.doczj.com/doc/b33583986.html,/icewee/archive/2012/05/19/378554.html

本文中的Base64Utils.java在其他随笔中已经贴出。Java证书生成命令如下,不做过多解释,可先到网上查询下资料,本文仅提供工具类代码:

把生成的密钥库和证书都放到类的同包下。

keytool -validity 365 -genkey -v -alias https://www.doczj.com/doc/b33583986.html, -keyalg RSA -keystor e D:\key\asdc.keystore -dname "CN=172.25.67.98,OU=stos,O=asdc,L=Haidi an,ST=Beijing,c=cn" -storepass 123456 -keypass 123456

keytool -export -v -alias https://www.doczj.com/doc/b33583986.html, -keystore D:\key\asdc.keystore -stor epass 123456 -rfc -file D:\key\asdc.cer

CertificateUtils.java

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.InputStream;

import java.io.OutputStream;

import java.nio.MappedByteBuffer;

import java.nio.channels.FileChannel;

import java.security.KeyStore;

import java.security.PrivateKey;

import java.security.PublicKey;

import java.security.Signature;

import java.security.cert.Certificate;

import java.security.cert.CertificateFactory;

import java.security.cert.X509Certificate;

import java.util.Date;

import javax.crypto.Cipher;

/**

*

* 数字签名/加密解密工具包

*

*

* @author IceWee

* @date 2012-4-26

* @version 1.0

*/

public class CertificateUtils {

/**

* Java密钥库(Java 密钥库,JKS)KEY_STORE

*/

public static final String KEY_STORE = "JKS";

public static final String X509 = "X.509";

/**

* 文件读取缓冲区大小

*/

private static final int CACHE_SIZE = 2048;

/**

* 最大文件加密块

*/

private static final int MAX_ENCRYPT_BLOCK = 117;

/**

* 最大文件解密块

*/

private static final int MAX_DECRYPT_BLOCK = 128;

/**

*

* 根据密钥库获得私钥

*

*

* @param keyStorePath 密钥库存储路径

* @param alias 密钥库别名

* @param password 密钥库密码

* @return

* @throws Exception

*/

private static PrivateKey getPrivateKey(String keyStorePath, String alias, St ring password)

throws Exception {

KeyStore keyStore = getKeyStore(keyStorePath, password);

PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, password.to CharArray());

return privateKey;

}

/**

*

* 获得密钥库

*

*

* @param keyStorePath 密钥库存储路径

* @param password 密钥库密码

* @return

* @throws Exception

*/

private static KeyStore getKeyStore(String keyStorePath, String password) throws Exception {

FileInputStream in = new FileInputStream(keyStorePath);

KeyStore keyStore = KeyStore.getInstance(KEY_STORE);

keyStore.load(in, password.toCharArray());

in.close();

return keyStore;

}

/**

*

* 根据证书获得公钥

*

*

* @param certificatePath 证书存储路径

* @return

* @throws Exception

*/

private static PublicKey getPublicKey(String certificatePath)

throws Exception {

Certificate certificate = getCertificate(certificatePath);

PublicKey publicKey = certificate.getPublicKey();

return publicKey;

}

/**

*

* 获得证书

*

*

* @param certificatePath 证书存储路径

* @return

* @throws Exception

*/

private static Certificate getCertificate(String certificatePath)

throws Exception {

CertificateFactory certificateFactory = CertificateFactory.getInstance(X50 9);

FileInputStream in = new FileInputStream(certificatePath);

Certificate certificate = certificateFactory.generateCertificate(in);

in.close();

return certificate;

}

/**

*

* 根据密钥库获得证书

*

*

* @param keyStorePath 密钥库存储路径

* @param alias 密钥库别名

* @param password 密钥库密码

* @return

* @throws Exception

*/

private static Certificate getCertificate(String keyStorePath, String alias, Stri ng password)

throws Exception {

KeyStore keyStore = getKeyStore(keyStorePath, password);

Certificate certificate = keyStore.getCertificate(alias);

return certificate;

}

/**

*

* 私钥加密

*

*

* @param data 源数据

* @param keyStorePath 密钥库存储路径

* @param alias 密钥库别名

* @param password 密钥库密码

* @return

* @throws Exception

*/

public static byte[] encryptByPrivateKey(byte[] data, String keyStorePath, String alias, String password)

throws Exception {

// 取得私钥

PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password);

Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());

cipher.init(Cipher.ENCRYPT_MODE, privateKey);

int inputLen = data.length;

ByteArrayOutputStream out = new ByteArrayOutputStream();

int offSet = 0;

byte[] cache;

int i = 0;

// 对数据分段加密

while (inputLen - offSet > 0) {

if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {

cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);

} else {

cache = cipher.doFinal(data, offSet, inputLen - offSet);

}

out.write(cache, 0, cache.length);

i++;

offSet = i * MAX_ENCRYPT_BLOCK;

}

byte[] encryptedData = out.toByteArray();

out.close();

return encryptedData;

}

/**

*

* 文件私钥加密

*

*

* 过大的文件可能会导致内存溢出

*

*

* @param filePath 文件路径

* @param keyStorePath 密钥库存储路径

* @param alias 密钥库别名

* @param password 密钥库密码

* @return

* @throws Exception

*/

public static byte[] encryptFileByPrivateKey(String filePath, String keyStore

Path, String alias, String password)

throws Exception {

byte[] data = fileToByte(filePath);

return encryptByPrivateKey(data, keyStorePath, alias, password);

}

/**

*

* 文件加密

*

*

* @param srcFilePath 源文件

* @param destFilePath 加密后文件

* @param keyStorePath 密钥库存储路径

* @param alias 密钥库别名

* @param password 密钥库密码

* @throws Exception

*/

public static void encryptFileByPrivateKey(String srcFilePath, String destFileP ath, String keyStorePath, String alias, String password)

throws Exception {

// 取得私钥

PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password);

Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());

cipher.init(Cipher.ENCRYPT_MODE, privateKey);

File srcFile = new File(srcFilePath);

FileInputStream in = new FileInputStream(srcFile);

File destFile = new File(destFilePath);

if (!destFile.getParentFile().exists()) {

destFile.getParentFile().mkdirs();

}

destFile.createNewFile();

OutputStream out = new FileOutputStream(destFile);

byte[] data = new byte[MAX_ENCRYPT_BLOCK];

byte[] encryptedData; // 加密块

while (in.read(data) != -1) {

encryptedData = cipher.doFinal(data);

out.write(encryptedData, 0, encryptedData.length);

out.flush();

}

out.close();

in.close();

}

/**

*

* 文件加密成BASE64编码的字符串

*

*

* @param filePath 文件路径

* @param keyStorePath 密钥库存储路径

* @param alias 密钥库别名

* @param password 密钥库密码

* @return

* @throws Exception

*/

public static String encryptFileToBase64ByPrivateKey(String filePath, String keyStorePath, String alias, String password)

throws Exception {

byte[] encryptedData = encryptFileByPrivateKey(filePath, keyStorePath, a lias, password);

return Base64Utils.encode(encryptedData);

}

/**

*

* 私钥解密

*

*

* @param encryptedData 已加密数据

* @param keyStorePath 密钥库存储路径

* @param alias 密钥库别名

* @param password 密钥库密码

* @return

* @throws Exception

*/

public static byte[] decryptByPrivateKey(byte[] encryptedData, String keySt orePath, String alias, String password)

throws Exception {

// 取得私钥

PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password);

Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());

cipher.init(Cipher.DECRYPT_MODE, privateKey);

// 解密byte数组最大长度限制: 128

int inputLen = encryptedData.length;

ByteArrayOutputStream out = new ByteArrayOutputStream();

int offSet = 0;

byte[] cache;

int i = 0;

// 对数据分段解密

while (inputLen - offSet > 0) {

if (inputLen - offSet > MAX_DECRYPT_BLOCK) {

cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOC K);

} else {

cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);

}

out.write(cache, 0, cache.length);

i++;

offSet = i * MAX_DECRYPT_BLOCK;

}

byte[] decryptedData = out.toByteArray();

out.close();

return decryptedData;

}

/**

*

* 公钥加密

*

*

* @param data 源数据

* @param certificatePath 证书存储路径

* @return

* @throws Exception

*/

public static byte[] encryptByPublicKey(byte[] data, String certificatePath) throws Exception {

// 取得公钥

PublicKey publicKey = getPublicKey(certificatePath);

Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());

cipher.init(Cipher.ENCRYPT_MODE, publicKey);

int inputLen = data.length;

ByteArrayOutputStream out = new ByteArrayOutputStream();

int offSet = 0;

byte[] cache;

int i = 0;

// 对数据分段加密

while (inputLen - offSet > 0) {

if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {

cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);

} else {

cache = cipher.doFinal(data, offSet, inputLen - offSet);

}

out.write(cache, 0, cache.length);

i++;

offSet = i * MAX_ENCRYPT_BLOCK;

}

byte[] encryptedData = out.toByteArray();

out.close();

return encryptedData;

}

/**

*

* 公钥解密

*

*

* @param encryptedData 已加密数据

* @param certificatePath 证书存储路径

* @return

* @throws Exception

*/

public static byte[] decryptByPublicKey(byte[] encryptedData, String certific atePath)

throws Exception {

PublicKey publicKey = getPublicKey(certificatePath);

Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());

cipher.init(Cipher.DECRYPT_MODE, publicKey);

int inputLen = encryptedData.length;

ByteArrayOutputStream out = new ByteArrayOutputStream();

int offSet = 0;

byte[] cache;

int i = 0;

// 对数据分段解密

while (inputLen - offSet > 0) {

if (inputLen - offSet > MAX_DECRYPT_BLOCK) {

cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOC K);

} else {

cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);

}

out.write(cache, 0, cache.length);

i++;

offSet = i * MAX_DECRYPT_BLOCK;

}

byte[] decryptedData = out.toByteArray();

out.close();

return decryptedData;

}

/**

*

* 文件解密

*

*

* @param srcFilePath 源文件

* @param destFilePath 目标文件

* @param certificatePath 证书存储路径

* @throws Exception

*/

public static void decryptFileByPublicKey(String srcFilePath, String destFilePa th, String certificatePath)

throws Exception {

PublicKey publicKey = getPublicKey(certificatePath);

Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());

cipher.init(Cipher.DECRYPT_MODE, publicKey);

File srcFile = new File(srcFilePath);

FileInputStream in = new FileInputStream(srcFile);

File destFile = new File(destFilePath);

if (!destFile.getParentFile().exists()) {

destFile.getParentFile().mkdirs();

}

destFile.createNewFile();

OutputStream out = new FileOutputStream(destFile);

byte[] data = new byte[MAX_DECRYPT_BLOCK];

byte[] decryptedData; // 解密块

while (in.read(data) != -1) {

decryptedData = cipher.doFinal(data);

out.write(decryptedData, 0, decryptedData.length);

out.flush();

}

out.close();

in.close();

}

/**

*

* 生成数据签名

*

* @param data 源数据

* @param keyStorePath 密钥库存储路径

* @param alias 密钥库别名

* @param password 密钥库密码

* @return

* @throws Exception

*/

public static byte[] sign(byte[] data, String keyStorePath, String alias, Stri ng password)

throws Exception {

// 获得证书

X509Certificate x509Certificate = (X509Certificate) getCertificate(keyStor ePath, alias, password);

// 获取私钥

KeyStore keyStore = getKeyStore(keyStorePath, password);

// 取得私钥

PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, password.to CharArray());

// 构建签名

Signature signature = Signature.getInstance(x509Certificate.getSigAlgNa me());

signature.initSign(privateKey);

signature.update(data);

return signature.sign();

}

/**

*

* 生成数据签名并以BASE64编码

*

*

* @param data 源数据

* @param keyStorePath 密钥库存储路径

* @param alias 密钥库别名

* @param password 密钥库密码

* @return

* @throws Exception

*/

public static String signToBase64(byte[] data, String keyStorePath, String a lias, String password)

throws Exception {

return Base64Utils.encode(sign(data, keyStorePath, alias, password));

}

/**

*

* 生成文件数据签名(BASE64)

*

*

* 需要先将文件私钥加密,再根据加密后的数据生成签名(BASE64),适用于小文件

*

*

* @param filePath 源文件

* @param keyStorePath 密钥库存储路径

* @param alias 密钥库别名

* @param password 密钥库密码

* @return

* @throws Exception

*/

public static String signFileToBase64WithEncrypt(String filePath, String keyS torePath, String alias, String password)

throws Exception {

byte[] encryptedData = encryptFileByPrivateKey(filePath, keyStorePath, a lias, password);

return signToBase64(encryptedData, keyStorePath, alias, password);

}

/**

*

* 生成文件签名

*

*

* 注意:

* 方法中使用了FileChannel,其巨大Bug就是不会释放文件句柄,导致签名的文件无法操作(移动或删除等)

* 该方法已被generateFileSign取代

*

*

* @param filePath 文件路径

* @param keyStorePath 密钥库存储路径

* @param alias 密钥库别名

* @param password 密钥库密码

* @return

* @throws Exception

*/

@Deprecated

public static byte[] signFile(String filePath, String keyStorePath, String alias,

String password)

throws Exception {

byte[] sign = new byte[0];

// 获得证书

X509Certificate x509Certificate = (X509Certificate) getCertificate(keyStor ePath, alias, password);

// 获取私钥

KeyStore keyStore = getKeyStore(keyStorePath, password);

// 取得私钥

PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, password.to CharArray());

// 构建签名

Signature signature = Signature.getInstance(x509Certificate.getSigAlgNa me());

signature.initSign(privateKey);

File file = new File(filePath);

if (file.exists()) {

FileInputStream in = new FileInputStream(file);

FileChannel fileChannel = in.getChannel();

MappedByteBuffer byteBuffer = fileChannel.map(FileChannel.MapMode. READ_ONLY, 0, file.length());

signature.update(byteBuffer);

fileChannel.close();

in.close();

sign = signature.sign();

}

return sign;

}

/**

*

* 生成文件数字签名

*

*

*

* 注意:

* 生成签名时update的byte数组大小和验证签名时的大小应相同,否则验证无法通过*

*

* @param filePath

* @param keyStorePath

* @param alias

* @param password

* @return

* @throws Exception

*/

public static byte[] generateFileSign(String filePath, String keyStorePath, St ring alias, String password)

throws Exception {

byte[] sign = new byte[0];

// 获得证书

X509Certificate x509Certificate = (X509Certificate) getCertificate(keyStor ePath, alias, password);

// 获取私钥

KeyStore keyStore = getKeyStore(keyStorePath, password);

// 取得私钥

PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, password.to CharArray());

// 构建签名

Signature signature = Signature.getInstance(x509Certificate.getSigAlgNa me());

signature.initSign(privateKey);

File file = new File(filePath);

if (file.exists()) {

FileInputStream in = new FileInputStream(file);

byte[] cache = new byte[CACHE_SIZE];

int nRead = 0;

while ((nRead = in.read(cache)) != -1) {

signature.update(cache, 0, nRead);

}

in.close();

sign = signature.sign();

}

return sign;

}

/**

*

* 文件签名成BASE64编码字符串

*

*

* @param filePath

* @param keyStorePath

* @param alias

* @param password

* @return

* @throws Exception

*/

public static String signFileToBase64(String filePath, String keyStorePath, S tring alias, String password)

throws Exception {

return Base64Utils.encode(generateFileSign(filePath, keyStorePath, alias, password));

}

/**

*

* 验证签名

*

*

* @param data 已加密数据

* @param sign 数据签名[BASE64]

* @param certificatePath 证书存储路径

* @return

* @throws Exception

*/

public static boolean verifySign(byte[] data, String sign, String certificatePa th)

throws Exception {

// 获得证书

X509Certificate x509Certificate = (X509Certificate) getCertificate(certifica tePath);

// 获得公钥

PublicKey publicKey = x509Certificate.getPublicKey();

// 构建签名

Signature signature = Signature.getInstance(x509Certificate.getSigAlgNa me());

signature.initVerify(publicKey);

signature.update(data);

return signature.verify(Base64Utils.decode(sign));

}

/**

*

* 校验文件完整性

*

*

* 鉴于FileChannel存在的巨大Bug,该方法已停用,被validateFileSign取代

*

*

* @param filePath 文件路径

* @param sign 数据签名[BASE64]

* @param certificatePath 证书存储路径

* @return

* @throws Exception

*/

@Deprecated

public static boolean verifyFileSign(String filePath, String sign, String certifi catePath)

throws Exception {

boolean result = false;

// 获得证书

X509Certificate x509Certificate = (X509Certificate) getCertificate(certifica tePath);

// 获得公钥

PublicKey publicKey = x509Certificate.getPublicKey();

// 构建签名

Signature signature = Signature.getInstance(x509Certificate.getSigAlgNa me());

signature.initVerify(publicKey);

File file = new File(filePath);

if (file.exists()) {

byte[] decodedSign = Base64Utils.decode(sign);

FileInputStream in = new FileInputStream(file);

FileChannel fileChannel = in.getChannel();

MappedByteBuffer byteBuffer = fileChannel.map(FileChannel.MapMode. READ_ONLY, 0, file.length());

signature.update(byteBuffer);

in.close();

result = signature.verify(decodedSign);

}

return result;

}

/**

*

* 校验文件签名

*

*

* @param filePath

* @param sign

* @param certificatePath

* @return

* @throws Exception

*/

public static boolean validateFileSign(String filePath, String sign, String cert

ificatePath)

throws Exception {

boolean result = false;

// 获得证书

X509Certificate x509Certificate = (X509Certificate) getCertificate(certifica tePath);

// 获得公钥

PublicKey publicKey = x509Certificate.getPublicKey();

// 构建签名

Signature signature = Signature.getInstance(x509Certificate.getSigAlgNa me());

signature.initVerify(publicKey);

File file = new File(filePath);

if (file.exists()) {

byte[] decodedSign = Base64Utils.decode(sign);

FileInputStream in = new FileInputStream(file);

byte[] cache = new byte[CACHE_SIZE];

int nRead = 0;

while ((nRead = in.read(cache)) != -1) {

signature.update(cache, 0, nRead);

}

in.close();

result = signature.verify(decodedSign);

}

return result;

}

/**

*

* BASE64解码->签名校验

*

*

* @param base64String BASE64编码字符串

* @param sign 数据签名[BASE64]

* @param certificatePath 证书存储路径

* @return

* @throws Exception

*/

public static boolean verifyBase64Sign(String base64String, String sign, Stri ng certificatePath)

throws Exception {

byte[] data = Base64Utils.decode(base64String);

return verifySign(data, sign, certificatePath);

}

/**

*

* BASE64解码->公钥解密-签名校验

*

*

*

* @param base64String BASE64编码字符串

* @param sign 数据签名[BASE64]

* @param certificatePath 证书存储路径

* @return

* @throws Exception

*/

public static boolean verifyBase64SignWithDecrypt(String base64String, Stri ng sign, String certificatePath)

throws Exception {

byte[] encryptedData = Base64Utils.decode(base64String);

byte[] data = decryptByPublicKey(encryptedData, certificatePath);

return verifySign(data, sign, certificatePath);

}

/**

*

* 文件公钥解密->签名校验

*

*

* @param encryptedFilePath 加密文件路径

* @param sign 数字证书[BASE64]

* @param certificatePath

* @return

* @throws Exception

*/

public static boolean verifyFileSignWithDecrypt(String encryptedFilePath, Stri ng sign, String certificatePath)

throws Exception {

byte[] encryptedData = fileToByte(encryptedFilePath);

byte[] data = decryptByPublicKey(encryptedData, certificatePath);

return verifySign(data, sign, certificatePath);

}

/**

*

* 校验证书当前是否有效

*

* @param certificate 证书

* @return

*/

public static boolean verifyCertificate(Certificate certificate) { return verifyCertificate(new Date(), certificate);

}

/**

*

* 验证证书是否过期或无效

*

*

* @param date 日期

* @param certificate 证书

* @return

*/

public static boolean verifyCertificate(Date date, Certificate certificate) { boolean isValid = true;

try {

X509Certificate x509Certificate = (X509Certificate) certificate;

x509Certificate.checkValidity(date);

} catch (Exception e) {

isValid = false;

}

return isValid;

}

/**

*

* 验证数字证书是在给定的日期是否有效

*

*

* @param date 日期

* @param certificatePath 证书存储路径

* @return

*/

public static boolean verifyCertificate(Date date, String certificatePath) { Certificate certificate;

try {

certificate = getCertificate(certificatePath);

return verifyCertificate(certificate);

} catch (Exception e) {

e.printStackTrace();

return false;

}

}

/**

*

* 验证数字证书是在给定的日期是否有效

*

*

* @param keyStorePath 密钥库存储路径

* @param alias 密钥库别名

* @param password 密钥库密码

* @return

*/

public static boolean verifyCertificate(Date date, String keyStorePath, String alias, String password) {

Certificate certificate;

try {

certificate = getCertificate(keyStorePath, alias, password);

return verifyCertificate(certificate);

} catch (Exception e) {

e.printStackTrace();

return false;

}

}

/**

*

* 验证数字证书当前是否有效

*

*

* @param keyStorePath 密钥库存储路径

* @param alias 密钥库别名

* @param password 密钥库密码

* @return

*/

public static boolean verifyCertificate(String keyStorePath, String alias, Stri ng password) {

return verifyCertificate(new Date(), keyStorePath, alias, password);

}

/**

*

* 验证数字证书当前是否有效

文件加密与解密—Java课程设计报告

JAVA课程设计题目:文件的加密与解密 姓名: 学号: 班级: 日期:

目录 一、设计思路 (3) 二、具体实现 (3) 三、运行调试与分析讨论 (8) 四、设计体会与小结 (11) 五、参考文献 (12) 六、附录 (12)

一、设计思路 自从Java技术出现以业,有关Java平台的安全性用由Java技术发展所引发的安全性问题,引起了越来越多的关注。目前,Java已经大量应用于各个领域,研究Java的安全性对于更好地利用Java具有深远的意义。使用Java的安全机制设计和实现安全系统更具有重要的应用价值。 本课程设计,主要实践Java安全中的JCE模块,包括密钥生成,Cipher对象初始化、加密模式、填充模式、底层算法参数传递,也涉及文件读写与对象输入输出流。 二、具体实现 本系统通过用户界面接收三个参数:明文文件、密文文件、口令。采用DES加密算法,密码分组链(Cipher Block Chaining,CBC)加密模式,PKCS#5-Padding的分组填充算法。因为CBC涉及到底层算法参数的解密密钥的传递,所以将明文文件中的字节块以密封对象(Sealed Object)的方式加密后,用对象流输出到密文文件,这样就将密文、算法参数、解密密钥三都密封到一个对象中了。口令的hash值作为产生密钥的参数。设计流程图如下所示: 文件加密与解密设计流程图

本系统中,包含Default,Shares,SecretKey,EncAndDec四个包共6个类组成。定义的几个参数:MAX_BUF_SIZE为每次从文件中读取的字节数,也是内存缓冲区的大小;加密算法为DES;加密模式是密码分组链(CBC)模式;分组填充方式是PKCS#5Padding。包和类结构图如下所示: 本课程设计,包和类结构图: 以下为包中的类的方法实现说明 Package Shares类结构图

企业财务系统的身份认证和电子签名解决方案

企业财务系统的CA身份认证和电子签名解决方案 1、用户需求: 总结用户需求如下: ●财务系统需要提升安全级别。财务系统的基本情况如下: ?财务系统的系统结构、操作系统、开发语言等(略) ?三种主要应用功能:预算申请、审批、修正;费用的申报;对财务系统查阅。 ●需要解决单纯的用户名/密码登录的脆弱性问题,确保登录财务系统的身 份的真实性。 ●需要对财务系统的操作、交易实现签名,满足不可抵赖性、事后溯性的 应用需求。 2、解决方案 具体设计方案如下: ●建设数字证书认证服务器,解决服务器和个人用户身份真实性的问题。 具体建设方案如下: ?证书服务器负责证书的日常管理。 ?管理终端完成证书的申请和发放工作。 ?为应用服务器颁发服务器证书,为个人用户颁发个人证书。登录时,实现双向验证,确保应用服务器身份和个人身份的真实性。 ?用户手持USB KEY,带有密码芯片算法的KEY,存储量大于等于32K。 用于私钥存储,确保私钥的安全。 ?采用SQL数据库,用于证书服务器生成证书和CRL的存储 ●建设数字签名中间件,对用户在财务系统中的操作实现数字签名,实现 抗抵赖的功能。具体建设方案如下: ?将数字签名服务器与应用服务器共同部署; ?在IE中部署签名插件; ?用户的操作需要用私钥进行签名; ?服务器端对用户的签名数据进行验签;

?应用数据和签名数据进行分别的存储。 具体部署的拓扑图如下(略) 3、用户收益 采用本方案后用户收益如下: ●通过强身份认证手段的采用,确保所有登录财务系统用户的身份的真实 性 对财务系统的操作、交易实现签名,满足不可抵赖性、事后溯性的应用需求。 ---------------------------------------------------------------------------------------------------------------------- 北京安软天地科技有限公司 专业的应用安全服务提供商,主要提供CA系统、SSL VPN设备,以及身份认证、电子签名、电子印章、文档保护、加密解密等解决方案,在金融、政府、电力、石油石化行业有大规模成熟应用。

信息安全之电子签名技术的实现

滨江学院 课程论文 题目数字签名的发展 院系计算机系 专业软件工程(动画方向)学生姓名陈婷 学号20092358009 指导教师朱节中 职称副教授 二O一二年五月二十日

数字签名的发展 陈婷 南京信息工程大学滨江学院软件工程(动画方向),南京210044 摘要: 数字签名是电子商务安全的一个非常重要的分支。随着电子商务的发展,电子签名的使用越来越多。实现电子签名的技术手段有很多种,但比较成熟的、世界先进国家目前普遍使用的电子签名技术还是基于PKI的数字签名技术。 关键词: 数字签名信息安全电子商务 1引言 1.1 研究背景 在当今信息社会,计算机网络技术得到了突飞猛进的发展。计算机网络日益成为工业、农业和国防等领域的重要信息交换手段,并逐渐渗透到社会的各个领域。在现实生活中,人们常常需要进行身份鉴别、数据完整性认证和抗否认。身份鉴别允许我们确认一个人的身份;数据完整性认证则帮助我们识别消息的真伪、是否完整;抗否认则防止人们否认自己曾经做过的行为。随着无纸化办公的发展,计算机网络的安全越来越受到重视,防止信息被未经授权的泄漏、篡改和破坏等都是亟待解决的问题。在Internet上,数字签名作为一项重要的安全技术,在保证数据的保密性、完整性、可用性、真实性和可控性方面起着极为重要的作用。同时由于信息技术的发展及其在商业、金融、法律等部门的普及, 数字签名技术又面临着新的挑战。 1.2 开发意义 数字签名是实现电子交易安全的核心技术之一,它在实现身份认证、数字完整性、不可抵赖性等功 能方面都有重要应用。尤其是在密钥分配、电子银行、电子证券、电子商务和电子政务等许多领域有重要 的应用价值。 2相关技术介绍 2.1PKI/CA 技术的介绍 PKI 就是公开密钥基础设施。它是利用公开密钥技术所构建的,解决网络安全问题的,普遍适用的一种基础设施。公开密钥技术也就是利用非对称算法的技术。说PKI 是基础设施,就意味着它对信息网络的重要。PKI 通过延伸到用户本地的接口,为各种应用提供安全的服务,如认证、身份识别、数字签名、

《Java范例开发大全》

下面是377个Java的例子。如果你是牛人,看看你能做出多少? 如果有人不相信这些例子都是Java做的,可以看看清华大学的《Java范例开发大全》实例1开发第一个Java程序 实例2自动提升 实例3自动转换 实例4常用基础类型之强制转换 实例5算术运算符 实例6关系运算符 实例7逻辑运算符 实例8位运算符 实例9移位运算符 实例10转型运算符 实例11常量与变量 实例12各种进制的转换 实例13 Java中的进制与移位运算符 实例14判断输入的年份是否为闰年 实例15抽奖活动 实例16xx乘法表 实例17如何列出素数 实例18 Java中的递归 实例19男生女生各多少人

实例20求xx数 实例21求任意一个正数的阶乘 实例22求n的n次方 实例23利用for循环输出几何图形 实例24xx 实例25求1到100之间的和 实例26存上100元需要多少天 实例27输出100之间的所有偶数 实例28如何判断回文数字 实例29输出100之间的所有奇数 实例30求最大的随机数 实例31判断字母分类 实例32优良及差 实例33打印任意一年日历 实例34一年四季的划分 实例35除0发生的算术异常(ArithmeticException) 实例36数组下标越界异常(ArrayIndexOutOfBoundsException)实例37数组元素类型不匹配异常(ArrayStoreException) 实例38强制类型转换异常(ClassCastException) 实例39索引越界异常(IndexOutOfBoundsException) 实例40空指针异常(NullPointerException)

2010-《数字签名与认证技术》讲义-4-7 章

第四章 短签名和基于身份的签名 ( 2 学时) 【讲授内容】 1. 双线性对 2. 短签名 3. 基于身份的签名 4.1 双线性对(pairing ) 为什么能够签名长度短?就是利用了双线性对的原因。(现在是一种趋势。) 假设21,G G 是两个群,阶数都是素数q 。1G 为加法群,2G 为乘法群。P 是1G 的任一生成元,aP 就是a 个P 相加。假设离散对数问题在21,G G 都是困难的。满足以下条件的映射211:G G G e →?叫做双线性映射(bilinear map ) (1) 双线性性:*∈∈=q ab Z b a and G Q P all for Q P e bQ aP e ,,,),(),(1 (2) 非退化性:如果P 是1G 的生成元,则),(P P e 是2G 的生成元,也即1),(≠P P e (3) 可计算性:容易计算1,), ,(G Q P all for Q P e ∈。 Bilinear map 也叫做Pairing 。椭圆曲线上或超椭圆曲线上的Weil 对和Tate 对可作为pairing 使用。(椭圆曲线上加群的离散对数问题,可构造数字签名。) 而基于椭圆曲线上的加法群的离散对数问题建立的方案,具有长度短,安全性高的优点。现在再结合双线性对的特性,可使方案具有长度短和证明简便的结合的优点。 计算DH (CDH )问题:给出一个随机生成元g 和随机元素G h h ∈21,,计算))(log (log 21h h g g g , 也即如果y x g h g h ==21,,计算输出xy g 。如果这是困难的,就说CDH 假设在G 成立。 对应于加法群: 1G 上的DDH (Decisional Diffie-Hellman )问题:给出*∈q Z c b a cP bP aP P ,,),,,,(,判断ab c =。这一问题可以在多项式时间解决(验证),(),(cP P e bP aP e =)。 习惯写法:),(),(),,,(B A e Q P e B Q P A V DDH =→ 1G 上CDH (Computational Diffie-Hellman )问题:给出*∈q Z b a bP aP P ,),,,(,计算 abP 。 Gap Diffie-Hellman group (GDH ):计算DDH 容易,计算CDH 困难。Pairing 的原象域domain 就是GDH 群的例子。

java文件加密解密课程设计

软件学院 课程设计报告书 课程名称面向对象程序设计 设计题目文本文档的加密与解密 专业班级财升本12-1班 学号 1220970120 姓名王微微 指导教师徐娇月 2013年 1 月

1 设计时间 2013年1月14日-2013年1月18日 2 设计目的 面向对象程序设计是一门实践性很强的计算机专业基础课程。通过实践加深学生对面向对象程序设计的理论、方法和基础知识的理解,掌握使用Java语言进行面向对象设计的基本方法,提高运用面向对象知识分析实际问题、解决实际问题的能力,提高学生的应用能力。 3 设计任务 对文件进行加密解密 4 设计内容 4.1 需求分析 (1)给定任意一个文本文件,进行加密,生成另一个文件。 (2)对加密后的文件还原。 4.2 总体设计 4.2.1 包的描述 导入了java.awt; java.awt.event; java.io; javax.swing等包。 4.2.2 类的描述 Myframe类;E1类。其中Myframe类继承Frame类;可以扩展Frame的功能并且可以实例化的多种功能,这个类也实现了ActionListener这个接口,它是Java中关于事件处理的一个接口,ActionListener用于接收操作事件的侦听器接口。对处理操作事件感兴趣的类可以实现此接口,而使用该类创建的对象可使用组件的addActionListener 方法向该组件注册。在发生操作事件时,调用该对象的actionPerformed 方法。 4.3 页面设计

图4.3-1 显示页面 代码实现: addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } });

如何用记事本编写一个简单的java代码

如何用记事本编写一个简单的j a v a代码 Document serial number【UU89WT-UU98YT-UU8CB-UUUT-UUT108】

一:怎么用记事本写第一个java代码 第一步:新建txt文档 首先我们在F盘新建一个txt文档,并命名为,如下图所示: 第二步:编写代码 我们双击打开:如下图所示 第三步:编写好代码 我们在记事本中写代码,写好后如下所示:

然后我们同时按Ctrl+s键保存,然后关闭记事本即可 上面的源代码如下: public class Test{//这里的Test为类名,这里类名要与我们刚才新建的记事本的名字必须一致,首字母大写 public static void main(String[] args){//java中的主函数的写法 "HelloWorld");//java中的输出语句写法 } } 第三步:打开控制台界面 我们在计算机中,打开如下图界面,

然后在这里,输入cmd,并按回车,然后弹出如图所示

第四步:在控制台中运行并输出 我们用鼠标点击一下里面黑色部分,然后输入F:然后回车,然后再输入javac 然后回车,最后输入java Test,就可以看到结果了,如下图所示:

红色圈出来部分就是结果了 二:温馨提示: 1,上面演算中在控制台中首先输入F:的原因是因为我在F盘建立一个文本文档,并命名为,如果你是把你的文档文档建立在D盘,则应该输入D: 以此类推。 2,如果你是在F盘下的CH文件夹建立一个记事本,并命名为,则输入的情况如下, cd CH表示转到CH这个文件夹下,然后再输入回车,再输入java Test 就可以看到运行结果了

数字签名及安全电子邮件详细步骤

数字签名及安全电子邮件 一、背景知识 使用个人证书,在电子邮件中至少有以下功能。 保密性:你可以使用收件人的数字证书对电子邮件进行加密。这样,只有收件人的私钥才能解密这封邮件,即使第三方截获邮件,由于没有收件人的私钥,也无法阅读该邮件。当然,要发送加密电子邮件,必须先拥有对方的数字证书。 认证身份:你可以使用你本人的数字证书对电子邮件进行数字签名,这样,收件人通过验证签名就可以确定你的身份,而不是他人冒充的。 完整性:如果验证数字签名有效,收件人不仅可以认证你的身份,还可以确信收到的邮件在传递的过程中没有被篡改。 不可否认性:数字签名要使用你本人数字证书中的私钥,而私钥仅你个人所有,所以,你不能对发送过的签名邮件进行否认。 1、电子邮件的重要性 由于越来越多的人通过电子邮件发送机密信息,因此确保电子邮件中发送的文档不是伪造的变得日趋重要。同时保证所发送的邮件不被除收件人以外的其他人截取和偷阅也同样重要。 通过使用 Outlook Express 和 Foxmail,可以在电子事务中证明身份,就象兑付支票时要出示有效证件一样。也可以使用数字证书来加密邮件以保护邮件的保密性。数字证书结合了 S/MIME 规范来确保电子邮件的安全。 2、对电子邮件进行数字签名 对电子邮件进行数字签名,能够确保电子邮件中发送的文档不是伪造的,即收件人能够确信该邮件来自于其声称的发件人,同时邮件从发件人的机器传达到接收人的机器没有经过任何改动。 当发件人在待发邮件中添加数字签名时,发件人就在邮件中加入了数字签名和自己的数字证书。邮件的接收方接收到该邮件后,首先判断发件人的证书是否有效(该证书是否是可信任的CA签发的,该证书是否在有效期内,该证书是否已经被撤销),如果证书有效,从发件人的证书中提取公钥信息,来验证邮件的数字签名是否有效。 3、对电子邮件进行加密 对电子邮件进行加密(使用接收人的数字证书中的公钥进行加密)可以保证所发送的邮件不被除收件人以外的其他人截取和偷阅。 当发件人对邮件进行加密时,使用接收人的数字证书中的公钥对邮件进行加密。邮件的接收方接收到该邮件后,使用自己的私钥对邮件进行解密,可以得到邮件的明文。因为使用公钥加密的数据,只有对应的私钥才可以解密,而对一封加密邮件来说,只有接收人才具有对应的私钥,也就是只有接收人才可以对邮件解密得到邮件的明文。其他任何人截获了该邮件都是无法识别的乱码。有效的保证了邮件内容的保密性。 4、电子邮件证书使用的简易性 如果接收到有问题的安全邮件,例如邮件已被篡改或发件人的数字证书已过期,则在被允许阅读邮件内容前,会看到一条安全警告,它详细说明了问题所在。根据警告中的信息,接收人可以决定是否查看邮件。 以上所述的签名和加密邮件的过程都是由邮件客户端程序(如Microsoft Outlook,Foxmail、Netscape Messager等)来完成。对于邮件的发送人来说,就是在邮件发送之前,简单的点击“签名”和“加密”按钮就可以了;对于邮件的接收人来说,邮件接收到后,邮件客户端程序更能够自动对签名邮件进行验证,对加密邮件进行解密,并将验证和解密结果

数字证书和数字签名的关系

数字证书和数字签名的关系 什么是数字证书? 由于Internet网电子商务系统技术使在网上购物的顾客能够极其方便轻松地获得商家和企业的信息,但同时也增加了对某些敏感或有价值的数据被滥用的风险. 为了保证互联网上电子交易及支付的安全性,保密性等,防范交易及支付过程中的欺诈行为,必须在网上建立一种信任机制。这就要求参加电子商务的买方和卖方都必须拥有合法的身份,并且在网上能够有效无误的被进行验证。数字证书是一种权威性的电子文档。它提供了一种在Internet上验证您身份的方式,其作用类似于司机的驾驶执照或日常生活中的身份证。它是由一个由权威机构----CA证书授权(Certificate Authority)中心发行的,人们可以在互联网交往中用它来识别对方的身份。当然在数字证书认证的过程中,证书认证中心(CA)作为权威的、公正的、可信赖的第三方,其作用是至关重要的。 数字证书也必须具有唯一性和可靠性。为了达到这一目的,需要采用很多技术来实现。通常,数字证书采用公钥体制,即利用一对互相匹配的密钥进行加密、解密。每个用户自己设定一把特定的仅为本人所有的私有密钥(私钥),用它进行解密和签名;同时设定一把公共密钥(公钥)并由本人公开,为一组用户所共享,用于加密和验证签名。当发送一份保密文件时,发送方使用接收方的公钥对数据加密,而接收方则使用自己的私钥解密,这样信息就可以安全无误地到达目的地了。通过数字的手段保证加密过程是一个不可逆过程,即只有用私有密钥才能解密。公开密钥技术解决了密钥发布的管理问题,用户可以公开其公开密钥,而保留其私有密钥。 数字证书颁发过程一般为:用户首先产生自己的密钥对,并将公共密钥及部分个人身份信息传送给认证中心。认证中心在核实身份后,将执行一些必要的步骤,以确信请求确实由用户发送而来,然后,认证中心将发给用户一个数字证书,该证书内包含用户的个人信息和他的公钥信息,同时还附有认证中心的签名信息。用户就可以使用自己的数字证书进行相关的各种活动。数字证书由独立的证书发行机构发布。数字证书各不相同,每种证书可提供不同级别的可信度。可以从证书发行机构获得您自己的数字证书。 目前的数字证书类型主要包括:个人数字证书、单位数字证书、单位员工数字证书、服务器证书、VPN证书、W AP证书、代码签名证书和表单签名证书。 随着Internet的普及、各种电子商务活动和电子政务活动的飞速发展,数字证书开始广泛地应用到各个领域之中,目前主要包括:发送安全电子邮件、访问安全站点、网上招标投标、网上签约、网上订购、安全网上公文传送、网上缴费、网上缴税、网上炒股、网上购物和网上报关等。 什么是数字签名?数字签名与电子签名是不是一回事? 电子签名和数字签名的内涵并不一样,数字签名是电子签名技术中的一种,不过两者的关系也很密切,目前电子签名法中提到的签名,一般指的就是"数字签名"。

两个基于RSA的特殊数字签名方案

龙源期刊网 https://www.doczj.com/doc/b33583986.html, 两个基于RSA的特殊数字签名方案 作者:蒋俊锋 来源:《电脑知识与技术》2008年第35期 摘要:介绍了数字签名背景、签名体制的形式化描述以及两个特殊的数字签名方案。对如何用RSA实现盲签名和多重数字签名方案进行了研究,分析了两种具体方案实现的安全性。最后总结了这两种特殊数字签名实现过程中算法设计的优劣。 关键词:数字签名;RSA;盲签名;多重签名 中图分类号:TP316文献标识码:A文章编号:1009-3044(2008)35-2095-02 Two RSA-based Special Digital Signature Schemes JIANG Jun-feng (Engineering of Information Hohai University,Changzhou 213022,China) Abstract: The background, the formal definition and some special form of digital signature are firstly introduced.The research of how to realize the blind signature and the multisignature with RSA signature scheme are carried out secondly. The virtue and shortcoming of the two realized special digital signature schemes and the research to be continued are lastly put forward. Key words: digital signature;RSA;blind signature;multisignature 1 引言 1.1 背景 签名一直被作为一种证明签名者身份的标识,它表明签名人看过乃至同意文件的内容。签 名人作出签名后将无法否认,并要为自己的签名负责。随着密码学的发展,数字签名(digital signature)克服了手写签名的缺点。数字签名[1]具有签名可信性、不可抵赖性、不可复制性、 不可伪造性和数据完整性的优点。2004年8月我国正式颁布了《中华人民共和国电子签名法》,确立了数字签名在我国的法律效力和地位。 1.2 数字签名的形式化定义

如何写一个正确的JAVA程序

若在定义中出现了常数初始化字符,则大写基本类型标识符中地所有字母.这样便可标志出它们属于编译期地常数.个人收集整理勿做商业用途 包()属于一种特殊情况:它们全都是小写字母,即便中间地单词亦是如此.对于域名扩展名称,如,,或者等,全部都应小写(这也是和地区别之一).个人收集整理勿做商业用途() 为了常规用途而创建一个类时,请采取“经典形式”,并包含对下述元素地定义:() () () ()( ) () 对于自己创建地每一个类,都考虑置入一个(),其中包含了用于测试那个类地代码.为使用一个项目中地类,我们没必要删除测试代码.若进行了任何形式地改动,可方便地返回测试.这些代码也可作为如何使用类地一个示例使用.个人收集整理勿做商业用途() 应将方法设计成简要地、功能性单元,用它描述和实现一个不连续地类接口部分.理想情况下,方法应简明扼要.若长度很大,可考虑通过某种方式将其分割成较短地几个方法.这样做也便于类内代码地重复使用(有些时候,方法必须非常大,但它们仍应只做同样地一件事情). () 设计一个类时,请设身处地为客户程序员考虑一下(类地使用方法应该是非常明确地).然后,再设身处地为管理代码地人考虑一下(预计有可能进行哪些形式地修改,想想用什么方法可把它们变得更简单).个人收集整理勿做商业用途 () 使类尽可能短小精悍,而且只解决一个特定地问题.下面是对类设计地一些建议:■一个复杂地开关语句:考虑采用“多形”机制 ■数量众多地方法涉及到类型差别极大地操作:考虑用几个类来分别实现 ■许多成员变量在特征上有很大地差别:考虑使用几个类. () 让一切东西都尽可能地“私有”——.可使库地某一部分“公共化”(一个方法、类或者一个字段等等),就永远不能把它拿出.若强行拿出,就可能破坏其他人现有地代码,使他们不得不重新编写和设计.若只公布自己必须公布地,就可放心大胆地改变其他任何东西.在多线程环境中,隐私是特别重要地一个因素——只有字段才能在非同步使用地情况下受到保护.个人收集整理勿做商业用途 () 谨惕“巨大对象综合症”.对一些习惯于顺序编程思维、且初涉领域地新手,往往喜欢先写一个顺序执行地程序,再把它嵌入一个或两个巨大地对象里.根据编程原理,对象表达地应该是应用程序地概念,而非应用程序本身.个人收集整理勿做商业用途() 若不得已进行一些不太雅观地编程,至少应该把那些代码置于一个类地内部. () 任何时候只要发现类与类之间结合得非常紧密,就需要考虑是否采用内部类,从而改善编码及维护工作(参见第章小节地“用内部类改进代码”).个人收集整理勿做商业用途() 尽可能细致地加上注释,并用注释文档语法生成自己地程序文档. () 避免使用“魔术数字”,这些数字很难与代码很好地配合.如以后需要修改它,无疑会成为一场噩梦,因为根本不知道“”到底是指“数组大小”还是“其他全然不同地东西”.所以,我们应创建一个常数,并为其使用具有说服力地描述性名称,并在整个程序中都采用常数标识符.这样可使程序更易理解以及更易维护.个人收集整理勿做商业用途 () 涉及构建器和异常地时候,通常希望重新丢弃在构建器中捕获地任何异常——如果它造成了那个对象地创建失败.这样一来,调用者就不会以为那个对象已正确地创建,从而盲目地继续.个人收集整理勿做商业用途

数字签名技术的认证和分类

数字签名技术的认证和分类 摘要随着计算机网络的迅速发展,人们经常利用网络进行信息的传递和文件的传输,这种传递的方式非常方便,因此很多商家开始在Internet中进行电子交易,为了保证交易的安全性数字签名因此诞生。 关键词数字签名;密码学;认证技术 现代密码学有很多组成部分,数字签名就是其中非常重要的一部分。数字签名也是公钥密码学的重要应用之一,其研究的方向有信息论、概率论、数论等多方面的内容。数字签名与手写签名相类似,它能够帮助验证签名者是否是消息的发出者;另一方面,数字签名被接收者保存下来,一旦出现争执的情况时,数字签名可以作为证据交给第三方(例如法院),由第三方验证此签名的合法性。 因此,使用数字签名可以避免产生以下四类问题: 1)否认。发送方或接收方在事后否认已经发送或接收过此份文件; 2)伪造。接收方自己或让他人帮助伪造出一份来自发送方的文件; 3)篡改。接收方对从发送方接到的文件内容进行全部或部分篡改; 4)冒充。在计算机网络中,某一用户冒充他人成为接收方或发送方。 数字签名是一种认证技术,它可以认证下面的内容: 1)实体认证。采取一定的鉴别协议来验证是否在正确的接收方和发送方之间进行信息通信; 2)身份认证。用户身份认证的目的是防止非法的用户访问该数据,采用数字签名技术进行身份认证在很大程序上提高了控制的力度; 3)报文认证。确认用户双方无误之后,就可以开始报文通信了。为了验证传送数据是否真实,可以采用数字签名对对数据进行验证。例如验证传送数据的时间、来源地、目的地等的真实性。 我们在日常生活中经常需要签名,例如在银行进行存款和取款时需要签名;在商业活动中需要在契约和合同上签名。在互联网上进行网上交易时需要进行数字签名。这种手写签名和数字签名的主要区别在于:手写签名因人而异,每个人都会因为书写习惯不同或常用字体不同而拥有不同的签名;数字签名是由0 和1 组成的字符串,消息内容不同则数字签名结果也不同。它们之间的主要区别在于:

手机银行数字签名实现方案

手机银行数字签名实现方案中国工商银行股份有限公司山东省分行 李顺吉 张昆 刘伟 普通数字签名广泛应用于银行的各类系统中,例如网上银行客户可以用U盾对缴费信息进行数字签名,以确保信息的完整性、保密性、不可否认性。但是手机银行则不同,受硬件环境的约束更加严格:不够强大的CPU、较小的内存,电池功耗受限等特点使其运算能力较低,不同输入设备使用的U盾类硬件设备接口也无法统一。各大银行目前均没有实现支持所有型号手机的数字签名系统,而普通口令卡因为安全性有限从而限制了支付额度。笔者根据手机银行特点,在基于身份的数字签名的基础上,结合门限密钥共享思想,将身份签名体制中的私钥进行拆分,提出无需证书的新型手机银行数字签名方案,使得手机银行客户仅通过口令即可对信息进行数字签名。 一、签名方案背景知识及系统参数介绍 1.基于椭圆曲线的密码系统 首先介绍循环群这一数学概念:一个非空集合G在二元运算乘法下满足结合律(对任意属于G的元素a、b、c都有(a*b)*c=a*(b*c));存在单位元e(任意属于G的元素a都有e*a=a*e=a);任意属于G的元素a均有逆元(存在属于G的元素b,使a*b=e);G中的某个元素g通过与自身的*运算生成了G中的所有元素,g记为生成元,这样的代数系统记为循环群。例如:任取素数q,小于等于q的正整数构成循环群,1为单位元,循环群中任意非单位元x均可作为生成元,对1≤i≤q,xi(mod q)的值恰好就是循环群中的所有元素。 q为素数,方程y2=x3+ax+b(mod q)的所有整数解(x,y)记为椭圆曲线上的点。下面的小写字母全部代表整数,大写字母代表椭圆曲线上的点。对点P及整数m<q,存在另一点Q满足点乘运算为Q=mP,存在另一点R满足点加运算R=P +Q。椭圆曲线模素数的整数解在点加和点乘运算下均构成循环群,点加循环群记为G。简单地说,l为一小正整数,合适的q元素下,y2=x3+ax+b(mod ql)的部分整数解也形成循环群,其点乘循环群记为V,则存在映射e:G×G->V记为双线性映射。双线性映射满足:①双线性性: 对任意G上的P,Q,R有e(P,Q+R) =e(P,Q)*e(P,R),e(P+Q,R)=e(P,R)*e(Q,R),由此可知,对所有G上点P,Q和所有a,b≤q,满足e(aP,bQ)=e(P,Q)ab; ②非退化性: 存在G上点P,Q使得e(P,Q)不等于V的单位元;③可计算性: 对任意G上点P,Q,存在着高效算法来计算e(P,Q)。笔者可以用超奇异椭圆曲线上的weil对或者改造的Tate对构造双线性映射。当q >2160时,上述椭圆曲线系统满足下列密码学性质。 离散对数问题:给定G上点P,Q,找出整数n,使得Q=nP是困难的。 CDH问题:给定三元组(P,aP,bP),对整数a,b,找出abP。 DDH问题:给定四元组(P,aP,bP,cP),整数a,b,c, c=ab(mod q)是否成立。 GDH问题:这是一类CDH问题难解,但是DDH问题易解的问题。 GDH群:CDH难解,DDH易解的群。上述椭圆曲线上的点就是GDH群。

看完这30个技巧让你写好Java代码

看完这30个技巧让你写好Java代码 2019.8整理 成为一个优秀的Java程序员,有着良好的代码编写习惯是必不可少的。下面就让我们来看看代码编写的30条建议吧。 (1) 类名首字母应该大写。字段、方法以及对象(句柄)的首字母应小写。对于所有标识符,其中包含的所有单词都应紧靠在一起,而且大写中间单词的首字母。例如: 若在定义中出现了常数初始化字符,则大写static final基本类型标识符中的所有字母。这样便可标志出它们属于编译期的常数。 Java包(Package)属于一种特殊情况:它们全都是小写字母,即便中间的单词亦是如此。对于域名扩展名称,如com,org,net或者edu等,全部都应小写(这也是Java 1.1和Java 1.2的区别之一)。 (2) 为了常规用途而创建一个类时,请采取”经典形式”,并包含对下述元素的定义:

(3) 对于自己创建的每一个类,都考虑置入一个main(),其中包含了用于测试那个类的代码。为使用一个项目中的类,我们没必要删除测试代码。若进行了任何形式的改动,可方便地返回测试。这些代码也可作为如何使用类的一个示例使用。 (4) 应将方法设计成简要的、功能性单元,用它描述和实现一个不连续的类接口部分。理想情况下,方法应简明扼要。若长度很大,可考虑通过某种方式将其分割成较短的几个方法。这样做也便于类内代码的重复使用(有些时候,方法必须非常大,但它们仍应只做同样的一件事情)。 (5) 设计一个类时,请设身处地为客户程序员考虑一下(类的使用方法应该是非常明确的)。然后,再设身处地为管理代码的人考虑一下(预计有可能进行哪些形式的修改,想想用什么方法可把它们变得更简单)。 (6) 使类尽可能短小精悍,而且只解决一个特定的问题。下面是对类设计的一些建议: ?一个复杂的开关语句:考虑采用”多形”机制 ?数量众多的方法涉及到类型差别极大的操作:考虑用几个类来分别实现 ?许多成员变量在特征上有很大的差别:考虑使用几个类 (7) 让一切东西都尽可能地”私有”–private。可使库的某一部分”公共化”(一个方法、类或者一个字段等等),就永远不能把它拿出。若强行拿出,就可能破坏其他人现有的代码,使他们不得不重新编写和设计。若只公布自己必须公布的,就可放心大胆地改变其他任何东西。在多线程环境中,隐私是特别重要的一个因素–只有private字段才能在非同步使用的情况下受到保护。 (8) 谨惕”巨大对象综合症”。对一些习惯于顺序编程思维、且初涉OOP领域的新手,往往喜欢先写一个顺序执行的程序,再把它嵌入一个或两个巨大的对象里。根据编程原理,对象表达的应该是应用程序的概念,而非应用程序本身。 (9) 若不得已进行一些不太雅观的编程,至少应该把那些代码置于一个类的内部。 (10) 任何时候只要发现类与类之间结合得非常紧密,就需要考虑是否采用内部类,从而改善编码及维护工作(参见第14章14.1.2小节的”用内部类改进代码”)。 (11) 尽可能细致地加上注释,并用javadoc注释文档语法生成自己的程序文档。

两种数字签名方案

两种数字签名技术 0902班贺信学号: 1.数字签名的基本概念 1.1 数字签名的定义 所谓数字签名就是附加在数据单元上的一些数据,或是对数据单元所作的密码变换。这种数据或变换允许数据单元的接收者用以确认数据单元的来源和数据单元的完整性并保护数据,防止被人(例如接收者)进行伪造。它是对电子形式的消息进行签名的一种方法,一个签名消息能在一个通信网络中传输。基于公钥密码体制和私钥密码体制都可以获得数字签名,目前主要是基于公钥密码体制的数字签名。包括普通数字签名和特殊数字签名。普通数字签名算法有RSA、ElGamal、Fiat-Shamir、Guillou- Quisquarter、Schnorr、Ong-Schnorr-Shamir 数字签名算法、DES/DSA,椭圆曲线数字签名算法和有限自动机数字签名算法等。特殊数字签名有盲签名、代理签名、群签名、不可否认签名、公平盲签名、门限签名、具有消息恢复功能的签名等,它与具体应用环境密切相关。 1.2 数字签名的基本要求 身份鉴别允许我们确认一个人的身份;数据完整性认证则帮助我们识别消息的真伪、是否完整;抗否认则防止人们否认自己曾经做过的行为。数字签名技术用来保证信息的完整性。“数字签名”是通过一个单向函数对要传送的报文进行处理后得到的,用以认证报文来源并

核实报文是否发生变化的一个字母数字串。数字签名可以解决否认、伪造、篡改及冒充等问题。类似于手书签名,数字签名也应满足一下基本要求: 1)收方能够确认或证实发方的签名,但不能伪造签名。 2)发方向收方发出签名的消息后,就不能再否认他所签发的消息,以保证他不能抵赖之前的交易行为。 3)收方对已收到的签名信息不能否认,即有收报认证。 4)第三者可以确认收发双方之间的信息传递,但不能伪造这一过程。 1.3 数字签名的原理 数字签名是通过密码技术对电子文档的电子形式的签名,并非是书面签名的数字图像化。它类似于手写签名或印章,也可以说它就是电子印章。我们对一些重要的文件进行签名,以确定它的有效性。但伪造传统的签名并不困难,这就使得数字签名与传统签名之间的重要差别更加突出:如果没有产生签名的私钥,要伪造由安全密码数字签名方案所产生的签名,计算上是不可行的。人们实际上也可以否认曾对一个议论中的文件签过名。但是否认一个数字签名却困难得多,这样做本质上证明在签名生成以前私钥的安全性就受到危害。这是由于数字签名的生成需要使用私钥,而它对应的公钥则用以验证签名。因而数字签名的一个重要性质就是非否认性,目前已经有一些方案,如数字证书,把一个实体(个人,组织或系统)的身份同一个私钥和公钥对"

JAVA实现古典置换密码的加密解密

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays; public class zhihuan { public static void main(String args[]) throws IOException{ System.out.println("请您输入需要的服务,1为加密,2为解密"); BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); int Choice=Integer.parseInt(br.readLine()); if(Choice==1) { System.out.println("您进入了加密程序"); System.out.print("请输入您需要加密的明文:"); String MingWen=br.readLine(); System.out.print("请输入加密秘钥:"); String key=br.readLine(); jiami(MingWen,key); Choice=2; } if(Choice==2) { System.out.println("您进入了解密程序"); System.out.print("请输入您需要解密的密文:"); String MiWen=br.readLine(); System.out.print("请输入解密秘钥:"); String key2=br.readLine(); jiemi(MiWen,key2); System.exit(0); } else { System.out.println("输入错误,请重新输入,1为加密,2为解密:\n"); System.exit(0); } } static void jiami(String mingwen,String key) { int hang=(int)Math.ceil((double)mingwen.length()/(double)key.length());//行数 int lie=key.length();//列数

RSA算法和RSA数字签名算法的实现

RSA算法和RSA数字签名算法的实现* 顾婷婷李涛 (四川大学计算机系(西区) 成都610065) 摘要RSA算法是一种公钥密码算法.实现RSA算法包括生成RSA密钥,用RSA加密规则和解密规则处理数据。RSA数字签名算法利用RSA算法实现数字签名。本文详述了RSA算法的基本原理, RSA 加密算法的实现以及如何利用RSA实现数字签名. 关键字RSA算法, 数字签名, 公开密钥, 私人密钥, 加密, 解密 中图分类号TP301 一、引言 随着网络技术的飞速发展,信息安全性已成为亟待解决的问题。公钥密码体制中,解密和加密密钥不同,解密和加密可分离,通信双方无须事先交换密钥就可建立起保密通信,较好地解决了传统密码体制在网络通信中出现的问题。另外,随着电子商务的发展,网络上资金的电子交换日益频繁,如何防止信息的伪造和欺骗也成为非常重要的问题。数字签名可以起到身份认证、核准数据完整性的作用。目前关于数字签名的研究主要集中基于公钥密码体制的数字签名。 公钥密码体制的特点是:为每个用户产生一对密钥(PK和SK);PK公开,SK保密;从PK推出SK是很困难的;A、B双方通信时,A通过任何途径取得B的公钥,用B的公钥加密信息。加密后的信息可通过任何不安全信道发送。B收到密文信息后,用自己私钥解密恢复出明文。 公钥密码体制已成为确保信息的安全性的关键技术。RSA公钥密码体制到目前为止还是一种认可为安全的体制。本文详述了RSA算法和用RSA算法实现数字签名的理论,以及它们在实际应用中的实现。 二、RSA算法和RSA数字签名算法的理论描述 1 RSA算法 RSA算法的理论基础是一种特殊的可逆模幂运算。 设n是两个不同奇素数p和q的积,即:n=pq, ?(n)=(p-1)(q-1)。 定义密钥空间 k={(n,p,q,d,e)|n=pq,p和q是素数,de≡1 mod ?(n),e为随机整数}, 对每一个k=(n,p,q,d,e), 定义加密变换为E k(x)=x b mod n,x∈Z n; 解密变换为D k(x)=y a mod n,y∈Z n,Z n为整数集合。 公开n和b,保密p,q和a. 为证明加密变换E k和解密变换 D k满足D k(E k(x))=x,这里不加证明的引用下面两个定理: 定理1(Euler)对任意的a∈Z n*,有a?(n)≡1 mod n,其中Z n*={x∈Z n|gcd(x,n)=1},?(·)表示Euler函数。 定理2 设p和q是两个不同的素数,n=pq, ?(n)=(p-1)(q-1),对任意的x∈Z n及任意的非负整数k,有 x k?(n)+1≡x mod n. 现在来证明RSA算法的加密变换和解密变换的正确性。 证明:对于加密变换E k和解密变换D k。因为ab≡1 mod ?(n),所以可设ab=t?(n)+1,t *本文受国家自然科学基金以及四川省学术带头人基金的资助。 顾婷婷,硕士生,李涛,教授,主要研究领域:人工智能与神经网络。

《Java程序设计》题目样例

【题目样例】 一、单选题 1.下面哪个特性不是Java具有的(D )。 A、“纯”面向对象 B、安全性高 C、可移植性好 D、运行速度快 2.下面哪个类型是Java中不支持的(C )。 A、布尔类型 B、字符串 C、指针 D、数组 3.下面哪个不属于Java语言的关键字(B )。 A、native B、const C、final D、finally 4.下面关于数组的使用,不正确的是(C )。 A、int a[] = {1, 2, 3}; B、int a[][] = {{ 1, 2 }, { 3, 4} }; C、int a = new int[6] for (int i=0; i<6; i++) a[i] = i * i; D、int a[][] =new int[2][ ]; int a[1] = new int [4]; int a[2] = new int[5]; 5.应用程序的main方法中有以下语句,则输出的结果是(A )。 String obj = new String("abcxyz"); for(int i = obj.length() - 1; I > 0; i--) System.out.print(obj.charAt(i)); A、zyxcba B、xyz C、zyxcb D、abcxyz 6.下面函数,哪一组不属于方法重载(A )。 A、int fun(int a, int b, float c) { … } float fun(int b, int a, float c) { … } B、int fun(int a, int b) { … } int fun(int a, int a, float c) { … } C、int fun(int a) { … } int fun(int a, int b) { … } D、int fun(int a, float b) { … } int fun(float b, int a) { … } 7.若创建RandomAccessFile类对象raf2: RandomAccessFile raf2 = new RandomAccessFile("1.txt", "rw"),该语句的功能是(B )。 A、打开当前目录下的文件1.txt,但只能向文件写入数据,不能从文件读取数据。 B、打开当前目录下的文件1.txt,既可以向文件写入数据,也可以从文件读取数据。 C、打开当前目录下的文件1.txt,但不能向文件写入数据,只能从文件读取数据。 D、以上说法都不对。 8.应用程序main方法中有以下语句,则输出的结果是(A )。 String s = "java@123456@"; int n = s.indexOf("@"); int k = s.indexOf("@", 5); String s2 = s.substring(n + 1, k);

相关主题
文本预览
相关文档 最新文档