我想了解通过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开发的软件。”

08-17 19:51