我想了解通过IAIK PKCS11Wrapper生成RSA 2048位密钥和使用IAIK PKCS11Wrapper并通过名为GenerateKeyPair.java
的示例对生成密钥对的IAIK PKCS11Provider之间的区别。
我将上述库和类与USB令牌ACS CryptoMate64结合使用。
当我使用PKCS11Wrapper并加载pkcs11.dll时,一切正常。生成密钥对。
但是,当我尝试通过IAIK PKCS11Provider类执行相同操作时,在尝试生成密钥对KeyPairGeneratorDemo.java
时会引发异常:
Exception in thread "main" iaik.pkcs.pkcs11.provider.IAIKPkcs11Exception: iaik.pkcs.pkcs11.wrapper.PKCS11Exception: CKR_ATTRIBUTE_VALUE_INVALID
at iaik.pkcs.pkcs11.provider.keypairgenerators.PKCS11KeyPairGenerator.generateKeyPair(Unknown Source)
at java.security.KeyPairGenerator$Delegate.generateKeyPair(KeyPairGenerator.java:650)
at KeyPairGenerationDemo.generateKeyPairSimple(KeyPairGenerationDemo.java:114)
at KeyPairGenerationDemo.main(KeyPairGenerationDemo.java:91)
这两种方法有什么区别?为什么通过IAIK PKCS11Provider生成密钥对会抛出CKR_ATTRIBUTE_VALUE_INVALID?我知道PKCS11标准中的常数是什么意思,但是我不完全理解为什么当IAIK PKCS11Wrapper成功实现此目标时会抛出该常数。
我还将附加两个正在使用的类。
GenerateKeyPair.java
// Copyright (c) 2002 Graz University of Technology. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. The end-user documentation included with the redistribution, if any, must
// include the following acknowledgment:
//
// "This product includes software developed by IAIK of Graz University of
// Technology."
//
// Alternately, this acknowledgment may appear in the software itself, if and
// wherever such third-party acknowledgments normally appear.
//
// 4. The names "Graz University of Technology" and "IAIK of Graz University of
// Technology" must not be used to endorse or promote products derived from this
// software without prior written permission.
//
// 5. Products derived from this software may not be called "IAIK PKCS Wrapper",
// nor may "IAIK" appear in their name, without prior written permission of
// Graz University of Technology.
//
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
import iaik.pkcs.pkcs11.Mechanism;
import iaik.pkcs.pkcs11.MechanismInfo;
import iaik.pkcs.pkcs11.Module;
import iaik.pkcs.pkcs11.Session;
import iaik.pkcs.pkcs11.Slot;
import iaik.pkcs.pkcs11.Token;
import iaik.pkcs.pkcs11.TokenException;
import iaik.pkcs.pkcs11.TokenInfo;
import iaik.pkcs.pkcs11.objects.KeyPair;
import iaik.pkcs.pkcs11.objects.Object;
import iaik.pkcs.pkcs11.objects.RSAPrivateKey;
import iaik.pkcs.pkcs11.objects.RSAPublicKey;
import iaik.pkcs.pkcs11.wrapper.Functions;
import iaik.pkcs.pkcs11.wrapper.PKCS11Constants;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Random;
/**
* This demo program generates a 2048 bit RSA key-pair on the token and writes
* the public key to a file.
*/
public class GenerateKeyPair {
static BufferedReader input_;
static PrintWriter output_;
static {
try {
//output_ = new PrintWriter(new FileWriter("SignAndVerify_output.txt"), true);
output_ = new PrintWriter(System.out, true);
input_ = new BufferedReader(new InputStreamReader(System.in));
} catch (Throwable thr) {
thr.printStackTrace();
output_ = new PrintWriter(System.out, true);
input_ = new BufferedReader(new InputStreamReader(System.in));
}
}
public static void main(String[] args)
throws IOException, TokenException, NoSuchAlgorithmException,
InvalidKeySpecException
{
if (args.length < 2) {
printUsage();
throw new IOException("Missing argument!");
}
Module pkcs11Module = Module.getInstance(args[0]);
pkcs11Module.initialize(null);
Slot[] slots = pkcs11Module.getSlotList(Module.SlotRequirement.TOKEN_PRESENT);
if (slots.length == 0) {
output_.println("No slot with present token found!");
throw new TokenException("No token found!");
}
Slot selectedSlot;
if (2 < args.length) selectedSlot = slots[Integer.parseInt(args[2])];
else selectedSlot = slots[0];
Token token = selectedSlot.getToken();
TokenInfo tokenInfo = token.getTokenInfo();
output_
.println("################################################################################");
output_.println("Information of Token:");
output_.println(tokenInfo);
output_
.println("################################################################################");
Session session;
if (3 < args.length) session = Util.openAuthorizedSession(token,
Token.SessionReadWriteBehavior.RW_SESSION, output_, input_, args[3]);
else session = Util.openAuthorizedSession(token,
Token.SessionReadWriteBehavior.RW_SESSION, output_, input_, null);
output_
.println("################################################################################");
output_.print("Generating new 2048 bit RSA key-pair... ");
output_.flush();
// first check out what attributes of the keys we may set
HashSet supportedMechanisms = new HashSet(Arrays.asList(token.getMechanismList()));
MechanismInfo signatureMechanismInfo;
if (supportedMechanisms.contains(Mechanism.get(PKCS11Constants.CKM_RSA_PKCS))) {
signatureMechanismInfo = token.getMechanismInfo(Mechanism
.get(PKCS11Constants.CKM_RSA_PKCS));
} else if (supportedMechanisms.contains(Mechanism.get(PKCS11Constants.CKM_RSA_X_509))) {
signatureMechanismInfo = token.getMechanismInfo(Mechanism
.get(PKCS11Constants.CKM_RSA_X_509));
} else if (supportedMechanisms.contains(Mechanism.get(PKCS11Constants.CKM_RSA_9796))) {
signatureMechanismInfo = token.getMechanismInfo(Mechanism
.get(PKCS11Constants.CKM_RSA_9796));
} else if (supportedMechanisms.contains(Mechanism
.get(PKCS11Constants.CKM_RSA_PKCS_OAEP))) {
signatureMechanismInfo = token.getMechanismInfo(Mechanism
.get(PKCS11Constants.CKM_RSA_PKCS_OAEP));
} else {
signatureMechanismInfo = null;
}
Mechanism keyPairGenerationMechanism = Mechanism
.get(PKCS11Constants.CKM_RSA_PKCS_KEY_PAIR_GEN);
RSAPublicKey rsaPublicKeyTemplate = new RSAPublicKey();
RSAPrivateKey rsaPrivateKeyTemplate = new RSAPrivateKey();
// set the general attributes for the public key
rsaPublicKeyTemplate.getModulusBits().setLongValue(new Long(2048));
byte[] publicExponentBytes = { 0x01, 0x00, 0x01 }; // 2^16 + 1
rsaPublicKeyTemplate.getPublicExponent().setByteArrayValue(publicExponentBytes);
rsaPublicKeyTemplate.getToken().setBooleanValue(Boolean.TRUE);
byte[] id = new byte[20];
new Random().nextBytes(id);
rsaPublicKeyTemplate.getId().setByteArrayValue(id);
//rsaPublicKeyTemplate.getLabel().setCharArrayValue(args[2].toCharArray());
rsaPrivateKeyTemplate.getSensitive().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getToken().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getPrivate().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getId().setByteArrayValue(id);
//byte[] subject = args[1].getBytes();
//rsaPrivateKeyTemplate.getSubject().setByteArrayValue(subject);
//rsaPrivateKeyTemplate.getLabel().setCharArrayValue(args[2].toCharArray());
// set the attributes in a way netscape does, this should work with most tokens
if (signatureMechanismInfo != null) {
rsaPublicKeyTemplate.getVerify().setBooleanValue(
new Boolean(signatureMechanismInfo.isVerify()));
rsaPublicKeyTemplate.getVerifyRecover().setBooleanValue(
new Boolean(signatureMechanismInfo.isVerifyRecover()));
rsaPublicKeyTemplate.getEncrypt().setBooleanValue(
new Boolean(signatureMechanismInfo.isEncrypt()));
rsaPublicKeyTemplate.getDerive().setBooleanValue(
new Boolean(signatureMechanismInfo.isDerive()));
rsaPublicKeyTemplate.getWrap().setBooleanValue(
new Boolean(signatureMechanismInfo.isWrap()));
rsaPrivateKeyTemplate.getSign().setBooleanValue(
new Boolean(signatureMechanismInfo.isSign()));
rsaPrivateKeyTemplate.getSignRecover().setBooleanValue(
new Boolean(signatureMechanismInfo.isSignRecover()));
rsaPrivateKeyTemplate.getDecrypt().setBooleanValue(
new Boolean(signatureMechanismInfo.isDecrypt()));
rsaPrivateKeyTemplate.getDerive().setBooleanValue(
new Boolean(signatureMechanismInfo.isDerive()));
rsaPrivateKeyTemplate.getUnwrap().setBooleanValue(
new Boolean(signatureMechanismInfo.isUnwrap()));
} else {
// if we have no information we assume these attributes
rsaPrivateKeyTemplate.getSign().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getDecrypt().setBooleanValue(Boolean.TRUE);
rsaPublicKeyTemplate.getVerify().setBooleanValue(Boolean.TRUE);
rsaPublicKeyTemplate.getEncrypt().setBooleanValue(Boolean.TRUE);
}
// netscape does not set these attribute, so we do no either
rsaPublicKeyTemplate.getKeyType().setPresent(false);
rsaPublicKeyTemplate.getObjectClass().setPresent(false);
rsaPrivateKeyTemplate.getKeyType().setPresent(false);
rsaPrivateKeyTemplate.getObjectClass().setPresent(false);
KeyPair generatedKeyPair = session.generateKeyPair(keyPairGenerationMechanism,
rsaPublicKeyTemplate, rsaPrivateKeyTemplate);
RSAPublicKey generatedRSAPublicKey = (RSAPublicKey) generatedKeyPair.getPublicKey();
RSAPrivateKey generatedRSAPrivateKey = (RSAPrivateKey) generatedKeyPair
.getPrivateKey();
// no we may work with the keys...
output_.println("Success");
output_.println("The public key is");
output_
.println("_______________________________________________________________________________");
output_.println(generatedRSAPublicKey);
output_
.println("_______________________________________________________________________________");
output_.println("The private key is");
output_
.println("_______________________________________________________________________________");
output_.println(generatedRSAPrivateKey);
output_
.println("_______________________________________________________________________________");
// write the public key to file
output_
.println("################################################################################");
output_.println("Writing the public key of the generated key-pair to file: "
+ args[1]);
RSAPublicKey exportableRsaPublicKey = generatedRSAPublicKey;
BigInteger modulus = new BigInteger(1, exportableRsaPublicKey.getModulus()
.getByteArrayValue());
BigInteger publicExponent = new BigInteger(1, exportableRsaPublicKey
.getPublicExponent().getByteArrayValue());
RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(modulus, publicExponent);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
java.security.interfaces.RSAPublicKey javaRsaPublicKey = (java.security.interfaces.RSAPublicKey) keyFactory
.generatePublic(rsaPublicKeySpec);
X509EncodedKeySpec x509EncodedPublicKey = (X509EncodedKeySpec) keyFactory.getKeySpec(
javaRsaPublicKey, X509EncodedKeySpec.class);
FileOutputStream publicKeyFileStream = new FileOutputStream(args[1]);
publicKeyFileStream.write(x509EncodedPublicKey.getEncoded());
publicKeyFileStream.flush();
publicKeyFileStream.close();
output_
.println("################################################################################");
// now we try to search for the generated keys
output_
.println("################################################################################");
output_
.println("Trying to search for the public key of the generated key-pair by ID: "
+ Functions.toHexString(id));
// set the search template for the public key
RSAPublicKey exportRsaPublicKeyTemplate = new RSAPublicKey();
exportRsaPublicKeyTemplate.getId().setByteArrayValue(id);
session.findObjectsInit(exportRsaPublicKeyTemplate);
Object[] foundPublicKeys = session.findObjects(1);
session.findObjectsFinal();
if (foundPublicKeys.length != 1) {
output_.println("Error: Cannot find the public key under the given ID!");
} else {
output_.println("Found public key!");
output_
.println("_______________________________________________________________________________");
output_.println(foundPublicKeys[0]);
output_
.println("_______________________________________________________________________________");
}
output_
.println("################################################################################");
session.closeSession();
pkcs11Module.finalize(null);
}
public static void printUsage() {
output_
.println("Usage: GenerateKeyPair <PKCS#11 module> <X.509 encoded public key file> [<slot>] [<pin>]");
output_.println(" e.g.: GenerateKeyPair pk2priv.dll publicKey.xpk");
output_.println("The given DLL must be in the search path of the system.");
}
}
KeyPairGeneratorDemo.java
// Copyright (C) 2002 IAIK
// http://jce.iaik.at
//
// Copyright (C) 2003 - 2013 Stiftung Secure Information and
// Communication Technologies SIC
// http://www.sic.st
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
// class and interface imports
import iaik.pkcs.pkcs11.Mechanism;
import iaik.pkcs.pkcs11.TokenException;
import iaik.pkcs.pkcs11.Version;
import iaik.pkcs.pkcs11.objects.Attribute;
import iaik.pkcs.pkcs11.objects.BooleanAttribute;
import iaik.pkcs.pkcs11.objects.GenericTemplate;
import iaik.pkcs.pkcs11.objects.PrivateKey;
import iaik.pkcs.pkcs11.objects.PublicKey;
import iaik.pkcs.pkcs11.objects.RSAPublicKey;
import iaik.pkcs.pkcs11.provider.IAIKPkcs11;
import iaik.pkcs.pkcs11.provider.keypairgenerators.PKCS11KeyPairGenerationSpec;
import iaik.pkcs.pkcs11.wrapper.PKCS11Constants;
import java.math.BigInteger;
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.DSAParameterSpec;
import javax.crypto.spec.DHParameterSpec;
/**
* This class shows a short demonstration of how to use this provider
* implementation for a key-pair generation.
*/
public class KeyPairGenerationDemo {
/**
* The PKCS#11 JCE provider.
*/
protected IAIKPkcs11 pkcs11Provider_;
/**
* The new key-pair.
*/
protected KeyPair keyPair_;
/**
* This empty constructor registers the new provider to the Java
* security system.
*/
public KeyPairGenerationDemo() {
DemoUtils.addSoftwareProvider();
pkcs11Provider_ = new IAIKPkcs11();
Security.addProvider(pkcs11Provider_);
}
public static void main(String[] args)
throws GeneralSecurityException
{
KeyPairGenerationDemo demo = new KeyPairGenerationDemo();
String algorithm = (args.length > 0) ? args[0] : "RSA"; // specify the required asymmetric algorithm, e.g. DSA, ECDSA, ...
demo.generateKeyPairSimple(algorithm);
demo.generateKeyPairMultipleProvider(algorithm);
demo.generateKeyPairDetailed(algorithm);
demo.printKeyPair(algorithm);
System.out.flush();
System.err.flush();
}
/**
* This method generates a key-pair on a simple and not flexible way.
* On some tokens this method creates permanent keys although not needed
* or the other way round (the default settings of the token are used).
* It stores the key-pair in the member variable <code>keyPair_</code>.
*
* @exception GeneralSecurityException
* If anything with the provider fails.
*/
public void generateKeyPairSimple(String algorithm)
throws GeneralSecurityException
{
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm,
pkcs11Provider_.getName());
keyPair_ = keyPairGenerator.generateKeyPair();
}
/**
* This method generates a key-pair for a specific instance of IAIK PKCS#11
* provider, if multiple instances are used in parallel.
* On some tokens this method creates permanent keys although not needed
* or the other way round (the default settings of the token are used).
* It stores the key-pair in the member variable <code>keyPair_</code>.
*
* @exception GeneralSecurityException
* If anything with the provider fails.
*/
public void generateKeyPairMultipleProvider(String algorithm)
throws GeneralSecurityException
{
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm,
pkcs11Provider_.getName());
// get a default template
iaik.pkcs.pkcs11.objects.KeyPair template = IAIKPkcs11.getGlobalKeyHandler()
.getKeyPairGeneratorTemplate(algorithm, -1);
keyPairGenerator
.initialize((PKCS11KeyPairGenerationSpec) new PKCS11KeyPairGenerationSpec(
template.getPublicKey(), template.getPrivateKey()).setUseUserRole(true));
keyPair_ = keyPairGenerator.generateKeyPair();
}
/**
* This method generates a key-pair by specifying the required attributes.
* It stores the key-pair in the member variable <code>keyPair_</code>.
*
* @exception GeneralSecurityException
* If anything with the provider fails.
*/
public void generateKeyPairDetailed(String algorithm)
throws GeneralSecurityException
{
//get private key template with attributes sign, private and sensitive set to true and attribute token set to false
PrivateKey privateKeyTemplate = KeyTemplateDemo
.getSignaturePrivateKeyTemplate(algorithm);
//get public key template with attribute verify set to true and attribute token set to false
PublicKey publicKeyTemplate = KeyTemplateDemo
.getSignaturePublicKeyTemplate(algorithm);
//additionally a label can be set for the keys
privateKeyTemplate.getLabel().setCharArrayValue("demoPrivateKey".toCharArray());
publicKeyTemplate.getLabel().setCharArrayValue("demoPublicKey".toCharArray());
//since PKCS#11 standard version 2.20 you can use these attributes
//example for RSA
if (algorithm.equalsIgnoreCase("RSA")) {
try {
Version cryptokiVersion = IAIKPkcs11.getModule().getInfo().getCryptokiVersion();
if ((cryptokiVersion.getMajor() >= 2) && (cryptokiVersion.getMinor() >= 20)) {
GenericTemplate wrapTemplate = new GenericTemplate();
BooleanAttribute encrypt = new BooleanAttribute(Attribute.ENCRYPT);
encrypt.setBooleanValue(Boolean.TRUE);
wrapTemplate.addAttribute(encrypt);
BooleanAttribute decrypt = new BooleanAttribute(Attribute.DECRYPT);
decrypt.setBooleanValue(Boolean.TRUE);
wrapTemplate.addAttribute(decrypt);
//only keys matching the template can be wrapped
publicKeyTemplate.getWrapTemplate().setAttributeArrayValue(wrapTemplate);
publicKeyTemplate.getWrap().setBooleanValue(Boolean.TRUE);
Mechanism[] allowedMechanisms = new Mechanism[2];
Mechanism mechanism1 = new Mechanism(PKCS11Constants.CKM_RSA_PKCS);
allowedMechanisms[0] = mechanism1;
Mechanism mechanism2 = new Mechanism(PKCS11Constants.CKM_SHA1_RSA_PKCS);
allowedMechanisms[1] = mechanism2;
//the key can only be used with the specified mechanisms (example for RSA)
publicKeyTemplate.getAllowedMechanisms().setMechanismAttributeArrayValue(
allowedMechanisms);
}
} catch (TokenException te) {
//ignore
}
}
AlgorithmParameterSpec keyPairGenerationSpec;
if (algorithm.equalsIgnoreCase("DSA")) {
AlgorithmParameterGenerator parameterGenerator = AlgorithmParameterGenerator
.getInstance("DSA", "IAIK");
parameterGenerator.init(1024);
AlgorithmParameters parameters = parameterGenerator.generateParameters();
DSAParameterSpec parameterSpec = (DSAParameterSpec) parameters
.getParameterSpec(DSAParameterSpec.class);
keyPairGenerationSpec = (AlgorithmParameterSpec) new PKCS11KeyPairGenerationSpec(
parameterSpec, publicKeyTemplate, privateKeyTemplate)
.setUseUserRole(false);
} else if (algorithm.equalsIgnoreCase("DH")) {
// for DH a derivation key template is needed
privateKeyTemplate.getSign().setPresent(false);
publicKeyTemplate.getVerify().setPresent(false);
privateKeyTemplate.getDerive().setBooleanValue(Boolean.TRUE);
publicKeyTemplate.getDerive().setBooleanValue(Boolean.TRUE);
BigInteger p = new BigInteger(
"12589626212164087648142963156054693968143531724127210882720574876034885248674417543636718639332350307931351997411747275642172788678286702755019900752157141");
BigInteger g = new BigInteger(
"798714029407796779983910943217886294189424826995758502398002980609131374451706837327391684051692474365177068254749526220588451409333567287210386365320453");
AlgorithmParameterSpec parameterSpec = new DHParameterSpec(p, g);
keyPairGenerationSpec = (AlgorithmParameterSpec) new PKCS11KeyPairGenerationSpec(
parameterSpec, publicKeyTemplate, privateKeyTemplate)
.setUseUserRole(false);
} else {
// for RSA key length has to be specified
if (algorithm.equalsIgnoreCase("RSA")) {
((RSAPublicKey) publicKeyTemplate).getModulusBits().setLongValue(new Long(1024));
}
keyPairGenerationSpec = (AlgorithmParameterSpec) new PKCS11KeyPairGenerationSpec(
publicKeyTemplate, privateKeyTemplate).setUseUserRole(false);
}
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm,
pkcs11Provider_.getName());
keyPairGenerator.initialize(keyPairGenerationSpec);
keyPair_ = keyPairGenerator.generateKeyPair();
System.out.println(" finished");
}
/**
* This method prints the generated key-pair (<code>keyPair_</code>).
*/
public void printKeyPair(String algorithm) {
System.out
.println("################################################################################");
System.out.println("The generated " + algorithm + " key-pair is:");
if (keyPair_ == null) {
System.out.println("null");
} else {
System.out
.println("________________________________________________________________________________");
System.out.println("Public key:");
System.out.println(keyPair_.getPublic());
System.out
.println("________________________________________________________________________________");
System.out.println("Private key:");
System.out.println(keyPair_.getPrivate());
}
System.out
.println("################################################################################");
}
}
最佳答案
我使用ACOS5遇到了同样的问题,我解决了这个问题:
调整证书的必填字段...:D
我很抱歉我不会说英语
Mechanism keyPairGenerationMechanism = Mechanism.RSA_PKCS_KEY_PAIR_GEN;
RSAPublicKey rsaPublicKeyTemplate = new RSAPublicKey();
RSAPrivateKey rsaPrivateKeyTemplate = new RSAPrivateKey();
rsaPublicKeyTemplate.getObjectClass().setPresent(true);
rsaPublicKeyTemplate.getToken().setBooleanValue(Boolean.TRUE);
rsaPublicKeyTemplate.getPrivate().setBooleanValue(Boolean.FALSE);
rsaPublicKeyTemplate.getModifiable().setBooleanValue(Boolean.TRUE);
rsaPublicKeyTemplate.getKeyType().setPresent(true);
byte[] id = new byte[5];
new Random().nextBytes(id);
rsaPublicKeyTemplate.getId().setByteArrayValue(id);
rsaPublicKeyTemplate.getLocal().setBooleanValue(Boolean.TRUE);
rsaPublicKeyTemplate.getKeyGenMechanism().setMechanism(keyPairGenerationMechanism);
rsaPublicKeyTemplate.getEncrypt().setBooleanValue(Boolean.TRUE);
rsaPublicKeyTemplate.getVerify().setBooleanValue(Boolean.TRUE);
rsaPublicKeyTemplate.getVerifyRecover().setBooleanValue(Boolean.TRUE);
rsaPublicKeyTemplate.getWrap().setBooleanValue(Boolean.TRUE);
byte[] mod = new byte[256];
new Random().nextBytes(mod);
rsaPublicKeyTemplate.getModulus().setByteArrayValue(mod);
rsaPublicKeyTemplate.getModulusBits().setLongValue(new Long(2048));
byte[] publicExponentBytes = { 0x01,0x00,0x01 }; // 2^16 + 1
rsaPublicKeyTemplate.getPublicExponent().setByteArrayValue(publicExponentBytes);
rsaPrivateKeyTemplate.getObjectClass().setPresent(true);
rsaPrivateKeyTemplate.getToken().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getPrivate().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getModifiable().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getKeyType().setPresent(true);
rsaPrivateKeyTemplate.getId().setByteArrayValue(id);
rsaPrivateKeyTemplate.getLocal().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getKeyGenMechanism().setMechanism(keyPairGenerationMechanism);
rsaPrivateKeyTemplate.getSensitive().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getDecrypt().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getSign().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getSignRecover().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getUnwrap().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getExtractable().setBooleanValue(Boolean.FALSE);
rsaPrivateKeyTemplate.getAlwaysSensitive().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getNeverExtractable().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getModulus().setByteArrayValue(mod);
rsaPrivateKeyTemplate.getPublicExponent().setByteArrayValue(publicExponentBytes);
密钥对生成的完整代码是
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package generatekeypair;
import iaik.pkcs.pkcs11.Mechanism;
import iaik.pkcs.pkcs11.MechanismInfo;
import iaik.pkcs.pkcs11.Module;
import iaik.pkcs.pkcs11.Session;
import iaik.pkcs.pkcs11.Slot;
import iaik.pkcs.pkcs11.Token;
import iaik.pkcs.pkcs11.TokenException;
import iaik.pkcs.pkcs11.TokenInfo;
import iaik.pkcs.pkcs11.objects.KeyPair;
import iaik.pkcs.pkcs11.objects.Object;
import iaik.pkcs.pkcs11.objects.RSAPrivateKey;
import iaik.pkcs.pkcs11.objects.RSAPublicKey;
import iaik.pkcs.pkcs11.wrapper.Functions;
import iaik.pkcs.pkcs11.wrapper.PKCS11Constants;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Random;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Administrador
*/
public class CrearCertiPar {
private Module pkcs11Module;
public CrearCertiPar(String librarayPath) throws TokenException {
try {
pkcs11Module = Module.getInstance(librarayPath);
pkcs11Module.initialize(null);
generarParcerti();
} catch (IOException ex) {
Logger.getLogger(CrearCertiPar.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void generarParcerti() throws TokenException {
Scanner teclado = new Scanner (System.in);
Slot[] slots = pkcs11Module.getSlotList(Module.SlotRequirement.TOKEN_PRESENT);
if (slots.length == 0) { //No tokens connected
System.out.println("Sorry, Couldn't find any token");
} else {
//Let's get the first slot
Slot selectedSlot = slots[0];
//Let's get the connected token
Token token = selectedSlot.getToken();
//Get the token infos
TokenInfo tokenInfo = token.getTokenInfo();
//System.out.println(tokenInfo);
Session session = token.openSession(Token.SessionType.SERIAL_SESSION, Token.SessionReadWriteBehavior.RW_SESSION, null, null);
//System.out.println(session);
if (tokenInfo.isLoginRequired()) {
if (tokenInfo.isProtectedAuthenticationPath()) {
session.login(Session.UserType.USER, null); // the token prompts the PIN by other means; e.g. PIN-pad
} else {
System.out.print("Enter user-PIN or press [return] to list just public objects: ");
System.out.flush();
//String userPINString = teclado.next();
String userPINString = "12345678";
System.out.println();
System.out.print("listing all" + ((userPINString.length() > 0) ? "" : " public") + " objects on token");
if (userPINString.length() > 0) {
// login user
session.login(Session.UserType.USER, userPINString.toCharArray());
}
}
}
System.out.println("############################# Generating new 1024 bit RSA key-pair ########################################");
HashSet supportedMechanisms = new HashSet(Arrays.asList(token.getMechanismList()));
MechanismInfo signatureMechanismInfo;
System.out.println("supportedMechanisms\n"+supportedMechanisms);
if (supportedMechanisms.contains(Mechanism.RSA_PKCS_KEY_PAIR_GEN)) {
signatureMechanismInfo = token.getMechanismInfo(Mechanism.RSA_PKCS_KEY_PAIR_GEN);
} else if (supportedMechanisms.contains(Mechanism.RSA_X_509)) {
signatureMechanismInfo = token.getMechanismInfo(Mechanism.RSA_X_509);
} else if (supportedMechanisms.contains(Mechanism.RSA_9796)) {
signatureMechanismInfo = token.getMechanismInfo(Mechanism.RSA_9796);
} else if (supportedMechanisms.contains(Mechanism.RSA_PKCS_OAEP)) {
signatureMechanismInfo = token.getMechanismInfo(Mechanism.RSA_PKCS_OAEP);
} else {
signatureMechanismInfo = null;
}
// System.out.println("signatureMechanismInfo\n"+signatureMechanismInfo);
Mechanism keyPairGenerationMechanism = Mechanism.RSA_PKCS_KEY_PAIR_GEN;
RSAPublicKey rsaPublicKeyTemplate = new RSAPublicKey();
RSAPrivateKey rsaPrivateKeyTemplate = new RSAPrivateKey();
rsaPublicKeyTemplate.getObjectClass().setPresent(true);
rsaPublicKeyTemplate.getToken().setBooleanValue(Boolean.TRUE);
rsaPublicKeyTemplate.getPrivate().setBooleanValue(Boolean.FALSE);
rsaPublicKeyTemplate.getModifiable().setBooleanValue(Boolean.TRUE);
rsaPublicKeyTemplate.getKeyType().setPresent(true);
byte[] id = new byte[5];
new Random().nextBytes(id);
rsaPublicKeyTemplate.getId().setByteArrayValue(id);
rsaPublicKeyTemplate.getLocal().setBooleanValue(Boolean.TRUE);
rsaPublicKeyTemplate.getKeyGenMechanism().setMechanism(keyPairGenerationMechanism);
rsaPublicKeyTemplate.getEncrypt().setBooleanValue(Boolean.TRUE);
rsaPublicKeyTemplate.getVerify().setBooleanValue(Boolean.TRUE);
rsaPublicKeyTemplate.getVerifyRecover().setBooleanValue(Boolean.TRUE);
rsaPublicKeyTemplate.getWrap().setBooleanValue(Boolean.TRUE);
byte[] mod = new byte[256];
new Random().nextBytes(mod);
rsaPublicKeyTemplate.getModulus().setByteArrayValue(mod);
rsaPublicKeyTemplate.getModulusBits().setLongValue(new Long(2048));
byte[] publicExponentBytes = { 0x01,0x00,0x01 }; // 2^16 + 1
rsaPublicKeyTemplate.getPublicExponent().setByteArrayValue(publicExponentBytes);
rsaPrivateKeyTemplate.getObjectClass().setPresent(true);
rsaPrivateKeyTemplate.getToken().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getPrivate().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getModifiable().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getKeyType().setPresent(true);
rsaPrivateKeyTemplate.getId().setByteArrayValue(id);
rsaPrivateKeyTemplate.getLocal().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getKeyGenMechanism().setMechanism(keyPairGenerationMechanism);
rsaPrivateKeyTemplate.getSensitive().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getDecrypt().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getSign().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getSignRecover().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getUnwrap().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getExtractable().setBooleanValue(Boolean.FALSE);
rsaPrivateKeyTemplate.getAlwaysSensitive().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getNeverExtractable().setBooleanValue(Boolean.TRUE);
rsaPrivateKeyTemplate.getModulus().setByteArrayValue(mod);
rsaPrivateKeyTemplate.getPublicExponent().setByteArrayValue(publicExponentBytes);
System.out.println("*********************************\n"+rsaPublicKeyTemplate);
System.out.println("*********************************\n");
System.out.println("*********************************\n"+rsaPrivateKeyTemplate);
System.out.println("*********************************\n");
KeyPair generatedKeyPair = session.generateKeyPair(keyPairGenerationMechanism,
rsaPublicKeyTemplate, rsaPrivateKeyTemplate);
// RSAPublicKey generatedRSAPublicKey = (RSAPublicKey) generatedKeyPair.getPublicKey();
// RSAPrivateKey generatedRSAPrivateKey = (RSAPrivateKey) generatedKeyPair
// .getPrivateKey();
// System.out.println("Success");
// System.out.println("The public key is");
// System.out.println("_______________________________________________________________________________");
// System.out.println(generatedRSAPublicKey);
// System.out.println("_______________________________________________________________________________");
// System.out.println("The private key is");
// System.out.println("_______________________________________________________________________________");
// System.out.println(generatedRSAPrivateKey);
// System.out.println("_______________________________________________________________________________");
//
}
}
}
再见...祝你好运
注意:此产品包括由格拉茨工业大学IAIK开发的软件。”