I have a problem and I tried searching a solution but couldn't find it. Someone please help me, thanks you so much.
String pkcs11Config = "name=CA-Token\nlibrary=C:/java/CA-Token_v2.dll\nslot=1";
InputStream is = new ByteArrayInputStream(pkcs11Config.getBytes())
SunPKCS11 providerPKCS11 = new sun.security.pkcs11.SunPKCS11(is); // (1)
Security.addProvider(providerPKCS11);
For this code, can we initialize the PKCS11 provider without using SunPKCS11?
It's been a while since this question was posted, but if you'd like to use a PKCS11 provider other than SunPKCS11, you can use:
IAIK PKCS11 wrapper https://jce.iaik.tugraz.at/products/core-crypto-toolkits/pkcs11-wrapper/
OpenSC https://github.com/OpenSC/OpenSC-Java/blob/master/pkcs11-test/src/test/java/org/opensc/test/pkcs11/PKCS11ProviderTestCase.java
Build your own provider by following Oracle tutorial https://docs.oracle.com/en/java/javase/17/security/howtoimplaprovider.html#GUID-C485394F-08C9-4D35-A245-1B82CDDBC031
You just need to instantiate them and register with "Security.addProvider(yourProvider)"
Related
I am getting below Exception which I observed when running Android app - it does not occurs when I run the code below as JUnit.
java.security.NoSuchAlgorithmException: ECDSA KeyPairGenerator not available
at java.security.KeyPairGenerator.getInstance(KeyPairGenerator.java:225)
at com.mhamdaoui.smartcardreader.CryptoUtils$Companion.getMerchantEphemeralPublicKey(CryptoUtils.kt:48)
at com.mhamdaoui.smartcardreader.MainActivity.onTagDiscovered(MainActivity.kt:80)
at android.nfc.NfcActivityManager.onTagDiscovered(NfcActivityManager.java:603)
at android.nfc.IAppCallback$Stub.onTransact(IAppCallback.java:83)
at android.os.Binder.execTransact(Binder.java:573)
The code:
Security.addProvider(BouncyCastleProvider())
val generator = KeyPairGenerator.getInstance("ECDSA")
val ecSpec = ECNamedCurveTable.getParameterSpec("secp256r1")
generator.initialize(ecSpec)
val keyPair = generator.generateKeyPair()
val publicKey = keyPair.public as ECPublicKey
return publicKey.q.getEncoded(true)
How to resolve this issue?
UPDATE
When I am creating JUnit in test (I am using Android Studio):
#Test
fun compressedGeneratorTest() {
Security.addProvider(BouncyCastleProvider())
val generator = KeyPairGenerator.getInstance("ECDSA")
val ecSpec = ECNamedCurveTable.getParameterSpec("secp256r1")
generator.initialize(ecSpec)
val keyPair = generator.generateKeyPair()
val publicKey = keyPair.public as ECPublicKey
val encoded = publicKey.q.getEncoded(true)
assert(true)
}
Everything works also. How to resolve this issue on App runtime?
The problem is that it is not possible to use BounceyCastle on Android - instead use SpongyCastle:
implementation 'com.madgag.spongycastle:prov:1.54.0.0'
implementation 'com.madgag.spongycastle:pkix:1.54.0.0'
And then initialize the provider with BouncyCastleProvider instance like below:
Security.addProvider(new org.spongycastle.jce.provider.BouncyCastleProvider())
Latest version of BouncyCastle libraries can be used to generate keypairs using ECDSA algorithm on Android device with the below mentioned steps.
Include the latest bouncy castle library by adding the below dependencies.
implementation "org.bouncycastle:bcprov-jdk15to18:1.68"
implementation "org.bouncycastle:bcpkix-jdk15to18:1.68"
Note: Refer Provider, PKIX to get the latest version details.
After adding the libraries, follow any of the below mentioned approach based on the mentioned need.
Approach 1
If you want to use the provider entire application level, replace the Android OS Bouncycastle provider with the provider from the added library using below line.
// Remove the OS provided bouncy castle provider
Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME)
// Add the bouncy castle provider from the added library
Security.addProvider(org.bouncycastle.jce.provider.BouncyCastleProvider())
Approach 2
If you don't want to replace the Provider throughout the application, you can pass the provider instance to the KeyPairGenerator like below.
Java
KeyPairGenerator generator = KeyPairGenerator.getInstance("ECDSA", new org.bouncycastle.jce.provider.BouncyCastleProvider())
Kotlin
val generator = KeyPairGenerator.getInstance("ECDSA", org.bouncycastle.jce.provider.BouncyCastleProvider())
You can use
implementation("org.bouncycastle:bcprov-jdk15on:1.70")
I would like to use my PKCS#11 enabled device as a source of SecureRandom.
So I have done the following:
Provider pkcs11provider = new sun.security.pkcs11.SunPKCS11(pkcs11config);
Security.addProvider(pkcs11provider);
byte[] rb = new byte[100];
SecureRandom sr = SecureRandom.getInstance("PKCS11", pkcs11provider);
sr.nextBytes(rb);
And I always get an exception:
Exception in thread "main" java.security.NoSuchAlgorithmException: no such algorithm: PKCS11 for provider SunPKCS11-HSM
at sun.security.jca.GetInstance.getService(GetInstance.java:101)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:218)
at java.security.SecureRandom.getInstance(SecureRandom.java:383)
What I am doing wrong? According JDK PKCS#11 Reference Guide "PKCS11" should be supported algorithm for SecureRandom.
"PKCS11" doesn't sound like an algorithm name. It is the provider name. A provider can have their own algorithm names for specific crypto operations. To see what all algorithms they have, you can run this code snippet to see them.
Set<Provider.Service> services = pkcs11provider.getServices();
services.forEach(service ->
{
// System.out.println(service.getType()); // --> Look for 'SecureRandom' type
System.out.println(service.getAlgorithm());
});
Look for 'SecureRandom' type, and that's the algorithm you have to pass in as the first argument in SecureRandom.getInstance(.., ..).
Hi i am currently porting an app to OpenSAML 3.2 and getting Problems with following:
1- SAMLSchemaBuilder has no getSAMLSchema methods:
Schema schema = SAMLSchemaBuilder.getSAML11Schema();
parserPoolManager.setSchema(schema)
2- The new org.opensaml.xmlsec.signature.support.SignatureValidator only accepts org.opensaml.security.credential.Credential not org.opensaml.xml.security.x509.X509Credential
BasicX509Credential publicCredential = new BasicX509Credential();
SignatureValidator.validate(signature, publicCredential);
Can someone help me?
Quick look on the JavaDoc, it looks like som difference in the constructor and then call getSAMLSchema instead of getSAML11Schema.
For your last question, try using the CredentialSupport class. It has a method for creating a Credential from a X509Certificate. getSimpleCredential
I am using SSL connection with X509 certificates provided from smartcards.
I have 2 identical tokens from athena . I initialise the keystores after I am reading the certificates, but when I am trying to to do the actual connection for the second token I am getting no provider found for my Private key.Connecting using the first token it's not affected, it works.
I tried adding different SunPCKS11 provider by specifing the slotIndexList to 1 , the number for the second token given by "slots = p11.C_GetSlotList(true)", but still the same error.
When I am listing the providers: I see the second provider, but java doesn't use it (I don't know why).
Provider _etpkcs11;
slots = p11.C_GetSlotList(true);
if(slot ==0)
{
String pkcs11config = "name=Athena\nlibrary=C:\WINDOWS\system32\asepkcs.dll";
byte[] pkcs11configBytes =pkcs11config.getBytes();
ByteArrayInputStream configStream = new ByteArrayInputStream(pkcs11configBytes);
etpkcs11 = new SunPKCS11(configStream);
Security.addProvider(etpkcs11);
}
the above works
the following doesn't work
if(slot ==1)
{
String pkcs11config1 = "name=Athenaslot1\nlibrary=C:\WINDOWS\system32\asepkcs.dll";
byte[] pkcs11configBytes1 =pkcs11config1.getBytes();
ByteArrayInputStream configStream1 = new ByteArrayInputStream(pkcs11configBytes1);
etpkcs11 = new SunPKCS11(configStream1);
Security.addProvider(etpkcs11);
}
the following
for(int j=0;j<Security.getProviders().length;j++)
{
System.out.println(Security.getProviders()[j].getName());
}
returns:
SunPKCS11-Athena
SunPKCS11-Athenaslot1
SUN
SunRsaSign
SunEC
SunJSSE
SunJCE
SunJGSS
SunSASL
XMLDSig
SunPCSC
and the error when using the second the second token:
No installed provider supports this key: sun.security.pkcs11.P11Key$P11PrivateKey
Thanks
PS: I need the both tokens on same machine
After having a look at these docs it is saying that the instantiation of the SunPKCS11 can take a slot in the configuration.
So maybe you could try
String pkcs11config1 = "name=Athenaslot1\nslot=1\nlibrary=C:\WINDOWS\system32\asepkcs.dll";
Even though you add 2 providers to the list of providers, the SunPKCS11 class caches the first instance. It seems like it always uses this instance all the time. That's the reason your second provider is not picked up/identified.
You might have to write some sneaky code to approach your use case. Right before you use your second provider, you have to clear the cached instance. You can refer to this post here. It is unanswered, but the code you should be looking for is
Field moduleMapField = PKCS11.class.getDeclaredField("moduleMap");
moduleMapField.setAccessible(true);
Map<?, ?> moduleMap = (Map<?, ?>) moduleMapField.get(<YOUR_FIRST_PROVIDER_INSTANCE>);
moduleMap.clear(); // force re-execution of C_Initialize next time
What this basically does is clearing the cached instance. And now you can proceed to add your second provider instance to interact with your second token.
I am using JSCH API to find length of RSA SSH keys .
I use the following code to do that:
KeyPairRSA KPR = (KeyPairRSA) KeyPairRSA.load(jsch, keypath);
System.out.println("size " +KPR.getKeySize());
This returns me always length 1024 .I think its bug with API itself.
Can anyone please tell me how to find length of RSA/DSA SSH keys?
Thanks a lot in advance.
I'm the author of JSch.
It is a bug or the incompleteness of KeyPair* classes.
They had been just introduced for the key-pair generation purposes.
But, in our internal development version, KeyPair* classes have been overhauled, and
that method has worked well.
# This is off-topic, but we have added the support for Putty's private key format, as a bonus! :-)
Anyway, the fix will be available in the next release, and if you can't wait for it,
replace KeyPairRSA#getKeySize() with the following,
public int getKeySize(){
return (new java.math.BigInteger(n_array)).bitLength();
}