Perhaps someone need to use USB-KEY or other Hardware Token to generate Digital Signature , through Microsoft CryptoAPI. Perhaps MS CryptoAPI is the only way for us to access Cryptography Device such as USB-Key. It is sure not a comfortable way because Java developers have to call CAPI funtions throught JNI(Java Native Interface). So there are some java-library to CALL CryptoAPI, but they are not free.
I hope to provide an OpenSource Java Library to do this thing : SecureX[https://sourceforge.net/projects/securex]
Here is some demo of what SecureX Library could do:
1, SecureX Library Arichtecture Demo
http://dev2dev.bea.com.cn/bbs/servlet/D2DServlet/download/29304-31620-211417-3031/securex.swf
2, SecureX USB-Key Demo
http://dev2dev.bea.com.cn/bbs/servlet/D2DServlet/download/29304-31620-213693-3060/HNISI_SecureX_USBKey.swf
OK, Came back to our topic, how to use java call CryptoAPI to produce signature.
You should know at least :
1, CryptoAPI are just a set of interface define by MS, and USB-Key Vendor just implement these interface so that our application can call the usb key to do some cryptographic operations(eg Signature, Hash, Encryption). There are a lot of CSPs located in your windows system. CSP is implementation, but we need not care about it, All we care is what CryptoAPI could do. See MSDN for more information.
2, For Java developer, they should use JNI to access CryptoAPI but it is not an easy thing since there are some encoding difference between JDK and Windows. For example, they should know how to convert the binary Private key stream to Java PrivateKey Object.
3, Perhaps some USB-Key vendor provide PKCS#11 CSP other than CryptoAPI CSP. PKCS# CSP is a RSA Standard [http://www.rsasecurity.com/rsalabs/node.asp?id=2133], It will be a good optional implement instead of CryptoAPI CSP.
Back to CryptoAPI CSP:
Java developer should do such a thing to generate a signature:
byte
[] data
=
"
http://openssl.blogjava.net
"
.getBytes();
SignatureUtils sigutil
=
new
SignatureUtils(
"
MD5
"
);
sigutil.initSign(privateKey);
sigutil.update(data,
0
,data.length);
byte
[] signature
=
sigutil.sign();
sigutil.initVerify(publicKey);
sigutil.update(data,
0
,data.length);
if
(
!
sigutil.verify(signature))
System.out.println(
"
The signature verification failed.
"
);
else
System.out.println(
"
The signature was successfully verified.
"
);
before we sign, we should provide a privatekey, in the java world, private key is stored in JKS file(Java Keystore), we could get the keyEntry out through:
keyStoreStream
=
new
FileInputStream(keyStoreFilename);
keystore
=
KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(keyStoreStream, keyStorePassword.toCharArray());
Key key
=
keystore.getKey(alias, keypassword);
if
(key
instanceof
PrivateKey)
return
(PrivateKey)key;
But on windows, private key is not stored in JKS, they stored in Windows Local CertStore or in USB-Key,and in most cases, private key are not allowed to Export!
In CryptoAPI's world, you should do the following things.
call CryptAcquireContext get HCRYPTPROV handle, also known as a csp handle
call CryptCreateHash to hash your data
call CryptSignHash to sign
CryptAcquireContext need Key container name 、CSP Name、CSP type、dwFlags。
CryptCreateHash need hash agorithm
CryptSignHash need dwKeySpec,right! it's the private key spec.
So, Java developer feel boring when he need to provide the private key.
The proper way is:
1, Use Alias to get the privatekey:
(a) if the private key is exportable, we can get it and change it to a Java Object
(b) if the private key is not exportable, we get the private key handle.
2, Sign the Hash
(a) if the private key is exportable, sigutil.initSign(privateKey) would do this job.
(b) if the private key is not exportable, we pass the private key handle to CSP,
and let CSP get the privatekey internally.
The program below is running under securex, and it can get the privatekey from
usb-key, and sign the data:
/** *//**
* 签名,并将XML签名结果保存到signatureFile中
* 需要3个条件
* 1,KeyAlias,用于获取私钥
* 2,source_filename_to_be_signed,确定被签名的数据源
* 3,签名算法
* @param save_signatureFile
*/
public static void sign()
{
byte abyte0[][];
if((abyte0 = CorKeyStoreJNI.getKey(getKeyAlias())) == null)
{
System.err.println("这是一条不可导出的钥匙!");
return;
}
if(abyte0.length == 0)
{
JCAPIRSAPrivateKey jcapikey =new JCAPIRSAPrivateKey(getKeyAlias().getBytes());
System.out.println(jcapikey.getAlgorithm()+":"+jcapikey.getPrivateExponent());
/** *//**
* 签名数据
*/
File sourcefile=new File(source_filename_to_be_signed);
byte[] data =null;
try {
data= FileUtils.getBytesFromFile(sourcefile);
} catch (IOException e1) {
e1.printStackTrace();
}
byte[] signature=null;
/** *//**
* 产生签名
* TODO, 使用正确的签名算法,比如MD5withRSA->MD5
*/
SignatureUtils sigutil=new SignatureUtils(getSignAgorithm());
try {
sigutil.initSign(jcapikey);
sigutil.update(data,0,data.length);
signature = sigutil.sign();
System.out.println("signature>>>.."+new String(signature));
setRawSignature(signature);
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace();
}
/** *//**
* 保存签名到save_signatureFile
* 也就是sign的参数
*/
try {
FileUtils.writeFile(getSaveSignatureFile(),signature);
} catch (IOException e) {
e.printStackTrace();
}
}
} How's it done?
1) Well, Suppose I USE an USB E-Key(CSP Vendor
:吉大正元www.jit.com.cn)
I know my PrivateKey Alias is , Locate In "My"
I get the private key through CoreKeyStoreJNI Class which has native jni method(getKey), by which I could
tell the csp which private key i want to use!
2) I get the file to byteArray which must be Hash before sign, because for Microsoft CAPI, its signobject can accept hash object only.
SignatureUtils sigutil=new SignatureUtils(getSignAgorithm());
the getSignAgorithm return "MD5withRSA" "SHA1withRSA" for most cases. It meas MD5 data before RSA Sign :)
3) when the
sigutil.sign(); is Excute, a native PIN-CallBack Windows is open, it will ask you for private key protected password(you can see it in my swf demo above).
type the correct PIN , My JIT CSP will call the correct sign cryptographic operations through the USB EKey drivers.
All the cryptographic operations(Hash, Sign) are performed on the USB-Key INTERNALLY, NOT by the KEY Drivers.
OK,then CSP get the signature and Signature Verify use only the Public Key and need not access the private key, It can perform by CSP or verify using JCE, as you like.
4) Haha, I've not yet told you that you need a DLL to Load before you call these API. Wait till I put my whole project to sourceforege SecureX(
http://securex.sourceforge.net/). Any Advice, please contact me on this blog or just join the QQ Group: 14966586
分享到:
相关推荐
CSP开发基础大全(CryptoAPI) CSP开发基础大全是指使用CryptoAPI开发加密应用程序的基础知识,涵盖了加密API的国际标准和规范、微软CryptoAPI、CryptoAPI在系统中的地位、信息隐藏、身份鉴别、完整性检验等方面的...
1. **开发符合CryptoSPI接口的CSP程序**:为了实现CSP的功能,需要开发一系列与CryptoSPI兼容的接口函数,这些函数能够将USBKEY的密码运算功能封装成CryptoAPI可调用的形式。 2. **智能卡操作系统(COS)的定制**...
根据给定文件信息,以下是关于CryptoAPI的详细知识点: CryptoAPI是微软提供的一套应用程序编程接口(API),旨在简化Windows平台下的公钥基础结构(PKI)应用开发。PKI是一系列技术的组合,用于管理数字证书和公钥...
### 使用Microsoft CryptoAPI进行数据加解密 #### 1. 加密方法概述 在信息安全领域,数据加密技术是一项至关重要的工具,它确保了数据在传输过程中不会被未授权的第三方窃取或篡改。根据加密过程中所使用的密钥...
微软加密服务体系CryptoAPI的结构如下图所示,微软加密服务体系包含三层结构和两个接口,分别为应用程序层、操作系统层(OS)、加密服务提供者层(Cryptographic Service Provider,CSP),CryptoAPI接口和加密服务提供...
本实验主题聚焦于信息安全领域,具体是利用Windows平台的CryptoAPI(Cryptographic Application Programming Interface)开发一套加解密工具软件。CryptoAPI是微软提供的一个强大的接口,它允许开发者在Windows系统...
CryptoAPI(Cryptographic Application Programming Interface)是微软Windows操作系统中提供的一组用于加密和解密的API接口,它为开发者提供了安全地处理敏感数据的能力。在本文中,我们将深入探讨CryptoAPI的基本...
**CryptoAPI概述** CryptoAPI(Cryptographic Application Programming Interface)是微软Windows操作系统中提供的一套用于加密和解密的API接口,它为开发者提供了强大的安全功能,包括数字签名、消息摘要、密钥...
**C语言下的CryptoAPI加密系统** CryptoAPI是微软Windows操作系统提供的一种用于安全编程的接口,它为应用程序提供了访问各种加密算法、哈希函数和数字签名等安全服务的能力。在C语言环境中,我们可以利用CryptoAPI...
**Windows的CryptoAPI接口** CryptoAPI是微软提供的一套用于加密、解密、签名和验证等安全操作的接口。这个接口使得开发者能够方便地在Windows操作系统中实现安全的数据传输和存储,确保信息的安全性。CryptoAPI的...
2. **CryptoAPI**:这是Windows操作系统提供的一个API,用于处理加密和解密操作,包括生成密钥对、数字签名和证书管理。 3. **RSA算法**:一种非对称加密算法,用于生成公钥和私钥。公钥用于加密,私钥用于解密,...
微软加密服务体系CryptoAPI的结构如下图所示,微软加密服务体系包含三层结构和两个接口,分别为应用程序层、操作系统层(OS)、加密服务提供者层(Cryptographic Service Provider,CSP),CryptoAPI接口和加密服务提供...
从给定的文件信息中,我们可以提取出关于使用CryptoAPI生成密钥的详细知识点,主要集中在以下几个方面: ### 1. CryptoAPI的概念及其重要性 CryptoAPI(加密应用程序接口)是由微软开发的一套应用程序接口,专门...
CryptoAPI是微软Windows操作系统提供的一套应用程序编程接口(API),用于实现各种安全服务,包括加密、解密、数字签名和哈希操作。这个例子代码是一个使用CryptoAPI进行加密和解密的VC6.0工程,它能帮助开发者理解...
Microsoft CryptoAPI(加密应用程序接口)是Windows操作系统内核的一部分,它为开发者提供了一种标准的方式来实现各种加密和安全相关的操作。这个压缩包包含了与CryptoAPI相关的源代码,可以帮助我们深入理解其工作...
本文整理了如何使用CryptoAPI 操作ukey进行数字签名。附上流程和部分代码,讲解cryptoapi实际应用以及应用中关键问题的解决方法,在这里,仅介绍数字签名(加密流程类似,但是,操作略有不同,所需要的函数也不同),...
*CryptoAPI数据加解密,它的流程为: *(加密模块)1.创建会话密钥 2.加密数据 3.安全保存或交换会话密钥 *(解密模块)1.获取会话密钥 2.解密数据 *它的加密是基于对称加密算法的(对称算法加密解密速度快),对...
本文将深入探讨标题为“crypto_cryptoapi.rar_CRYPTO_Crypto++_cryptoAPI”的主题,该主题涉及到一个用C++编写的加密库,用于封装微软的CryptoAPI(Cryptographic Application Programming Interface)。这个压缩包...
利用CryptoAPI对硬件CSP操作的分析分享.pdf
### CryptoAPI中文手册知识点 #### 一、CryptoAPI概述与发展历程 CryptoAPI,全称“Cryptographic Application Programming Interface”,即密码学应用编程接口,是由微软公司开发的一套应用于Windows操作系统上的...