Calculating Amazon MWS Signature using Java / Filemaker - java

We've been trying to calculate the Amazon Signature for the past few days using the Java code provided on Amazon's site.
I'm not a seasoned Java developer, but we've managed to use the basis of their code found at http://docs.developer.amazonservices.com/en_US/dev_guide/DG_ClientLibraries.html#DG_OwnClientLibrary__Signatures to generate a signature but we keep getting a "signature doesn't match" error that we're running into a wall debugging. Here is our current Java code with account specific information omitted:
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import java.sql.*;
import java.util.Date;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
import java.util.Date;
public class Main {
private static final String CHARACTER_ENCODING = "UTF-8";
final static String ALGORITHM = "HmacSHA256";
public static void main(String[] args) throws Exception {
// Change this secret key to yours
String secretKey = "XXXXXXXXXXXXXXXXXXXXXX"; // This secret key does have a forward slash in it (3rd to last character), would that adversely affect anything?
// Use the endpoint for your marketplace
String serviceUrl = "https://mws.amazonservices.com/Orders/2011-01-01";
// Create set of parameters needed and store in a map
HashMap<String, String> parameters = new HashMap<String,String>();
// Add required parameters. Change these as needed.
parameters.put("AWSAccessKeyId", urlEncode("XXXXXXXXXXX"));
parameters.put("Action", urlEncode("ListOrders"));
parameters.put("MarketplaceId.Id.1", urlEncode("ATVPDKIKX0DER"));
parameters.put("Merchant", urlEncode("ALZYDHGPLQNLD"));
parameters.put("OrderStatus.Status.1", urlEncode("PartiallyShipped"));
parameters.put("OrderStatus.Status.2", urlEncode("Unshipped"));
parameters.put("SignatureMethod", urlEncode(ALGORITHM));
parameters.put("SignatureVersion", urlEncode("2"));
parameters.put("Timestamp", urlEncode("2014-01-29T22:11:00Z"));
parameters.put("Version", urlEncode("2011-01-01"));
//parameters.put("SubmittedFromDate", urlEncode("2014-01-28T15:05:00Z"));
// Format the parameters as they will appear in final format
// (without the signature parameter)
String formattedParameters = calculateStringToSignV2(parameters, serviceUrl);
//System.out.println(formattedParameters);
String signature = sign(formattedParameters, secretKey);
System.out.println(urlEncode(signature));
// Add signature to the parameters and display final results
parameters.put("Signature", urlEncode(signature));
System.out.println(calculateStringToSignV2(parameters, serviceUrl));
// TEST AREA
// Signiture sig = new Signiture();
// String HMAC = sig.calculateRFC2104HMAC(parameters, secretKey);
// TEST AREA
}
/* If Signature Version is 2, string to sign is based on following:
*
* 1. The HTTP Request Method followed by an ASCII newline (%0A)
*
* 2. The HTTP Host header in the form of lowercase host,
* followed by an ASCII newline.
*
* 3. The URL encoded HTTP absolute path component of the URI
* (up to but not including the query string parameters);
* if this is empty use a forward '/'. This parameter is followed
* by an ASCII newline.
*
* 4. The concatenation of all query string components (names and
* values) as UTF-8 characters which are URL encoded as per RFC
* 3986 (hex characters MUST be uppercase), sorted using
* lexicographic byte ordering. Parameter names are separated from
* their values by the '=' character (ASCII character 61), even if
* the value is empty. Pairs of parameter and values are separated
* by the '&' character (ASCII code 38).
*
*/
private static String calculateStringToSignV2(Map<String, String> parameters, String serviceUrl)
throws SignatureException, URISyntaxException {
// Sort the parameters alphabetically by storing
// in TreeMap structure
Map<String, String> sorted = new TreeMap<String, String>();
sorted.putAll(parameters);
// Set endpoint value
URI endpoint = new URI(serviceUrl.toLowerCase());
// Create flattened (String) representation
StringBuilder data = new StringBuilder();
/*data.append("POST\n");
data.append(endpoint.getHost());
data.append("\n/");
data.append("\n");*/
Iterator<Entry<String, String>> pairs = sorted.entrySet().iterator();
while (pairs.hasNext()) {
Map.Entry<String, String> pair = pairs.next();
if (pair.getValue() != null) {
data.append( pair.getKey() + "=" + pair.getValue());
}
else {
data.append( pair.getKey() + "=");
}
// Delimit parameters with ampersand (&)
if (pairs.hasNext()) {
data.append( "&");
}
}
return data.toString();
}
/*
* Sign the text with the given secret key and convert to base64
*/
private static String sign(String data, String secretKey)
throws NoSuchAlgorithmException, InvalidKeyException,
IllegalStateException, UnsupportedEncodingException {
Mac mac = Mac.getInstance(ALGORITHM);
//System.out.println(mac);//
mac.init(new SecretKeySpec(secretKey.getBytes(CHARACTER_ENCODING), ALGORITHM));
//System.out.println(mac);//
byte[] signature = mac.doFinal(data.getBytes(CHARACTER_ENCODING));
//System.out.println(signature);//
String signatureBase64 = new String(Base64.encodeBase64(signature), CHARACTER_ENCODING);
System.out.println(signatureBase64);
return new String(signatureBase64);
}
private static String urlEncode(String rawValue) {
String value = (rawValue == null) ? "" : rawValue;
String encoded = null;
try {
encoded = URLEncoder.encode(value, CHARACTER_ENCODING)
.replace("+", "%20")
.replace("*", "%2A")
.replace("%7E","~");
} catch (UnsupportedEncodingException e) {
System.err.println("Unknown encoding: " + CHARACTER_ENCODING);
e.printStackTrace();
}
return encoded;
}
}
Right now we're testing this by hand because I'm trying to submit requests/manage the data through a Filemaker Database, so I may be adding the signature back to the URL query incorrectly. I'm assuming that 1) all of the parameters need to be listed in the query alphabetically and 2) the signature is the only exception that gets appended, last.
For example:
AWSAccessKeyId=AKIAITPQPJO62G4LAE7Q&Action=ListOrders&MarketplaceId.Id.1=XXXXXXXXXXX&Merchant=XXXXXXXXXXX&OrderStatus.Status.1=PartiallyShipped&OrderStatus.Status.2=Unshipped&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2014-01-29T22%3A11%3A00Z&Version=2011-01-01&Signature=tNufJeONZlscTlHs%2FLAWBs7zwsfpIaQcUK%2B5XIPJpcQ%3D
But the response I keep getting is this:
<?xml version="1.0"?>
<ErrorResponse xmlns="https://mws.amazonservices.com/Orders/2011-01-01">
<Error>
<Type>Sender</Type>
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.</Message>
</Error>
<RequestID>7532e668-c660-4db6-b129-f5fe5d3fad63</RequestID>
</ErrorResponse>
Any insight would be greatly appreciated. Debugging is fun but I need to get past this already!

Related

Using Google Translate Java Library, Languages with special chars return question marks

I have setup a Java program that I made for my apprenticeship project that takes in a JSON file of English strings and outputs a different language JSON file that is defined in the console. Some languages like french and Italian will output with the correct translations whereas Russian or Japanese will output with question marks as seen in the images bellow.
I had searched around at saw that I needed to get the bytes of my string and then encode that to UTF-8 I did do this but was still getting question marks so I started to use he standard charsets built into Java and tried different ways of encoding/decoding the string I tried this:
and this gave me a different output of this : Ð?Ñ?ивеÑ?
package com.bis.propertyfiletranslator;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.List;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.translate.Translate;
import com.google.api.services.translate.model.TranslationsListResponse;
import com.google.api.services.translate.model.TranslationsResource;
public class Translator {
public static Translate.Translations.List list;
private static final Charset UTF_8 = Charset.forName("UTF-8");
private static final Charset ISO = Charset.forName("ISO-8859-1");
public static void translateJSONMapThroughGoogle(String input, String output, String API, String language,
List<String> subLists) throws IOException, GeneralSecurityException {
Translate t = new Translate.Builder(GoogleNetHttpTransport.newTrustedTransport(),
JacksonFactory.getDefaultInstance(), null).setApplicationName("PhoenUX-Google-Translate").build();
try {
list = t.new Translations().list(subLists, language).setFormat("text");
list.setKey(API);
} catch (GoogleJsonResponseException e) {
if (e.getDetails().getMessage().equals("Invalid Value")) {
System.err.println(
"\n Language not currently supported, check the accepted language codes and try again.\n\n Language Requested: "
+ language);
} else {
System.out.println(e.getDetails().getMessage());
}
}
for (TranslationsResource translationsResource : response.getTranslations()) {
for (String key : JSONFunctions.jsonHashMap.keySet()) {
JSONFunctions.jsonHashMap.remove(key);
String value = translationsResource.getTranslatedText();
String encoded = new String(value.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
JSONFunctions.jsonHashMap.put(key, encoded);
System.out.println(encoded);
break;
}
}
JSONFunctions.outputTranslationsBackToJson(output);
}
}
So this is using the google cloud library, I added a sysout so I could see the results of what I had tried, so this code should be all you need to replicate it.
I expect the output of "Hello" to be "Привет"(russian) actual output is ???? or Ð?Ñ?ивеÑ? dependent on the encoding I use.
String encoded = new String(...) is dead wrong. Just
put(key, value):
Note that System.out.println will always have problems as the OS encoding might be some Windows ANSI encoding. Then it is likely non Unicode-capable - and String contains Unicode.

Export ASN.1 format, then encode with Base64 JAVA

I want to make a custom ASN.1 structure, what consists of 3 PrintableString's and 1 OctetString. I am using BouncyCastle framework to work with this.
So I set in my class the needed parameters, and now I have to return this structure in ASN.1 format, and then encode it with Base64 (its parameter is byte[]), then into PEM format.
So my question is, that what type of object do I have to return from method getASN1format()?
My code:
import org.bouncycastle.asn1.*;
import java.io.IOException;
public class ASN1Handshake1 implements ASN1Encodable {
private DERPrintableString A, B, ID_PASS;
private ASN1OctetString ID_K;
public ASN1Handshake1(String A, String B, String ID_K, String ID_PASS, TTP TTPs ) throws IOException {
this.A = new DERPrintableString(A);
this.B = new DERPrintableString(B);
this.ID_K = new DEROctetString(ID_K.getBytes());
this.ID_PASS = new DERPrintableString(ID_PASS);
}
public ?? getASN1format(){
//TODO
}
#Override
public ASN1Primitive toASN1Primitive() {
return null;
}
}
I'm using Bouncy Castle 1.57 (bcprov-jdk15on) for this code.
First of all, keep in mind that ASN.1 is not a format per se, it's a description language that defines a structure, and PEM is a format that uses base 64. Many cryptography standards use ASN.1 to define their data structures, and PEM or DER (Distinguished Encoding Rules) to serialize those structures.
So, if you want to get the ASN.1 structure and format it to base64, you can do as below. You don't need a getASN1format method, just use the existent ones.
The fields can't just be "loose" in the ASN.1 structure. So I decided to put them in a sequence (using org.bouncycastle.asn1.DERSequence class), which is the best choice to store fields of a structure. I put them in the order they're declared, but of course you can choose any order you want.
I've also changed the variables names to follow Java's code conventions (names start with lowercase letters). So the class code is:
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERPrintableString;
import org.bouncycastle.asn1.DERSequence;
public class ASN1Handshake1 extends ASN1Object {
private DERPrintableString a, b, idPass;
private ASN1OctetString idK;
// removed TTPs parameter (it wasn't using it)
public ASN1Handshake1(String a, String b, String idK, String idPass) {
this.a = new DERPrintableString(a);
this.b = new DERPrintableString(b);
this.idK = new DEROctetString(idK.getBytes());
this.idPass = new DERPrintableString(idPass);
}
// returns a DERSequence containing all the fields
#Override
public ASN1Primitive toASN1Primitive() {
ASN1Encodable[] v = new ASN1Encodable[] { this.a, this.b, this.idK, this.idPass };
return new DERSequence(v);
}
}
To create a handshake object and convert it to base64 (the code below is not handling exceptions, so add the try/catch block accordingly):
import org.bouncycastle.util.encoders.Base64;
// create handshake object with some sample data
ASN1Handshake1 handshake = new ASN1Handshake1("a", "b", "ID_K", "ID_PASS");
// convert it to base64
String base64String = new String(Base64.encode(handshake.getEncoded()));
System.out.println(base64String);
This will output the handshake structure in base64 format:
MBUTAWETAWIEBElEX0sTB0lEX1BBU1M=
Please note that this is not a complete PEM (with headers like -----BEGIN CERTIFICATE-----) because your custom structure is not a predefined standard. So, you'll have to stay with this base64 generic string.
To check that the base64 string contains the ASN.1 sequence, just do:
// read from base64 String
ASN1Sequence seq = (ASN1Sequence) DERSequence.fromByteArray(Base64.decode(base64String.getBytes()));
int n = seq.size();
for (int i = 0; i < n; i++) {
ASN1Encodable obj = seq.getObjectAt(i);
if (obj instanceof DEROctetString) {
System.out.println(new String(((DEROctetString) obj).getOctets()));
} else {
System.out.println(obj);
}
}
The output is:
a
b
ID_K
ID_PASS

Are my json stored in postgres corrupted?

I implemented a Java pipeline which stores some objects in postgres (9.5).
Objects are first serialized to a json string with jackson (2.5.4) and then sent with JDBC to the DBMS in a JSON column type.
When needed objects are read from database, deserialized and used by the application.
The problem is that when i try to query my data with psql I have some strange error, linked with UTF-8:
kronos=# select payload from messages where payload->>'errorMessage' = 'some error';
ERROR: unsupported Unicode escape sequence
DETAIL: \u0000 cannot be converted to text.
CONTEXT: JSON data, line 1:
...globalIdResolution":"GENERATED","authorFullName":...
I am not particularly worried, since my application can write and read all the data in the RDBMS. Is this a psql issue or maybe I am doing something wrong? Is there a way to be sure that my data should be accessible from any application, also if not java+jackson based?
I think this couldn't be jackson's fault, since I tried with a unit test but the string doens't seem to contain \0000 char:
package it.celi.dd.kronos.json;
import static org.junit.Assert.*;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonUTF8Test {
#Test
public void test() throws JsonProcessingException {
final ObjectMapper objectMapper = new ObjectMapper();
final String utf8 = "؏ـــطــہ";
final Map<String, Object> map = new HashMap<>();
map.put("content", txt(1600) + utf8 + txt(500));
final String json = objectMapper.writeValueAsString(map);
final int jsonBoilerplate = "{\"content\":\"".length() + "\"}".length();
assertEquals(1600 + utf8.length() + 500 + jsonBoilerplate, json.length());
System.out.println(json.length());
assertEquals("{\"content\":\"" + txt(1600) + utf8 + txt(500) + "\"}", json);
}
private String txt(final int chars) {
final StringBuilder builder = new StringBuilder();
for(int i = 0; i < chars; i ++) {
builder.append('a');
}
return builder.toString();
}
}

Google MD5 cracker (in java)

i find below code for Cracking Md5 hashes : (from : aboulton.blogspot.com.tr)
package md5crack;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* #author Adam Boulton - Using Google to crack MD5
*/
public class MD5Cracker {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
if(args[0] == null || args[0].isEmpty())
{
System.out.println("-= Google MD5 Cracker =-");
System.out.println("-= Adam Boulton - 2010 =- ");
System.out.println("Usage: MD5crack <hash>");
}
String hash = args[0];
String url = String.format("https://www.google.com/search?q=%s", hash);
try {
URL oracle = new URL(url);
URLConnection conn = oracle.openConnection();
//keep Google happy, otherwise connection refused.
conn.setRequestProperty("user-agent", "Mozilla/5.0 Windows NT6.1 WOW64 AppleWebKit/535.7 KHTML, like Gecko Chrome/16.0.912.63 Safari/535.7");
BufferedReader in = new BufferedReader(
new InputStreamReader(
conn.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
String[] words = inputLine.split("\\s+");
for (String word : words) {
String wordHash = DigestUtils.md5Hex(word);
if (wordHash.equals(hash)) {
System.out.println("[*] Found: " + word);
System.exit(0);
}
}
}
System.out.println("[!] No results.");
in.close();
} catch (IOException ex) {
Logger.getLogger(MD5Cracker.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
but in this line i have an error :
String wordHash = DigestUtils.md5Hex(word);
Error :
DigestUtils cannot be resolved
How can i fix that ?
and this is good method or Class for crack and finding Decoded MD5 hash ?
How we can use this with Optimizing on android ?
Thanks.
Your program doesn´t know what DigestUtils is standing for.
You need to either import it, or download codec from the appache common jar and reference it as external jar into your project and import it afterwards
... and this is good method or Class for crack and finding Decoded MD5 hash?
Is it going to be effective? In general, probably not.
There are 340,282,366,920,938,463,463,374,607,431,768,211,456 possible different MD5 hashes. If you have an MD5 hash for an arbitrary string or document, then the chances of finding that hash in Google search results is vanishingly small.
Indeed, it is pretty obvious that Google's search engines wouldn't be able to index more than a miniscule fraction of the possible MD5 hashes. According to this article, the "big 4" internet companies were estimated to have ~1,200 Petabytes of storage in 2013. That's a factor of ~1020 too small just to store all possible MD5 hashes.
However, if you can identify a use-case where mappings between relevant strings and MD5 hashes are systematically published in web pages, then this approach might work ... for those strings. One such use-case would be MD5 hashes for email addresses, if someone has published the mappings in pages that Google indexes.

IAIK PCKS11Provider VS IAIK PKCS11Wrapper key generation

I would like to understand the difference between generating RSA 2048 bit keys through IAIK PKCS11Wrapper, where I am using the example class named GenerateKeyPair.java, and IAIK PKCS11Provider which also uses IAIK PKCS11Wrapper and generate key pair through example class named KeyPairGeneratorDemo.java.
I am using the above libraries and classes with USB token ACS CryptoMate64.
When I use PKCS11Wrapper and load my pkcs11.dll everything works fine. Key pair is generated.
But when I am trying to do the same through IAIK PKCS11Provider class, it is throwing an exception when trying to generate key pair keyPair_ = keyPairGenerator.generateKeyPair();:
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)
What's the difference between these two approaches? And why is key pair generation through IAIK PKCS11Provider throwing CKR_ATTRIBUTE_VALUE_INVALID? I know what that constant mean in PKCS11 standard but I don't fully understand why it is thrown when IAIK PKCS11Wrapper was successfull with that...
I am also attaching two classes that I'm using.
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("################################################################################");
}
}
I had the same problem using a ACOS5, I solved this:
adjusting the required fields for the certificate ...: D
i'm sorrry i don't speak english
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);
the complete code for key pair geneation is
/*
* 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("_______________________________________________________________________________");
//
}
}
}
bye... good luck
note: This product includes software developed by IAIK of Graz University of Technology."

Categories

Resources