Bill
Bill

Reputation: 11822

How to delete public keys from a PKCS#11 security token in Java?

I would like modify a software which was written in Java. The software should be able to create public and private keys on a HSM and also be able to delete them. I would like to do these tasks by using the Sun PKCS#11 Provider. I have managed to create and store the keys and the corresponding certificates and also managed to delete the private key and the certificates. However I can not figure out how to delete the public key.

The Java source creating and storing the keys and the certificates is similar to this:

KeyStore keyStore = KeyStore.getInstance("PKCS11", "SunPKCS11-libtpm2");
keyStore.load(null, "userpin".toCharArray());

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "SunPKCS11-libtpm2");
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.generateKeyPair();

keyStore.setKeyEntry("WorkstationAuthentication", keyPair.getPrivate(), null, getCertificates());

After running this Java code the pkcs11-tool utility shows that the key pair and the certificates are stored:

# pkcs11-tool --module /usr/lib/x86_64-linux-gnu/pkcs11/libtpm2_pkcs11.so --slot-index=0 --list-objects --login
Using slot with index 0 (0x1)
Logging in to "myfirsttoken".
Please enter User PIN:

Public Key Object; RSA 2048 bits
  label:
  Usage:      encrypt, verify
  Access:     local

Private Key Object; RSA
  label:
  ID:         534b5332303038576f726b73746174696f6e41757468656e7469636174696f6e
  Usage:      decrypt, sign
  Access:     always sensitive, never extractable, local
  Allowed mechanisms: RSA-X-509,RSA-PKCS-OAEP,RSA-PKCS,SHA1-RSA-PKCS,SHA256-RSA-PKCS,SHA384-RSA-PKCS,SHA512-RSA-PKCS,RSA-PKCS-PSS,SHA1-RSA-PKCS-PSS,SHA256-RSA-PKCS-PSS,SHA384-RSA-PKCS-PSS,SHA512-RSA-PKCS-PSS

Certificate Object; type = X.509 cert
  label:      WorkstationAuthentication
  subject:    DN:
  ID:         534b5332303038576f726b73746174696f6e41757468656e7469636174696f6e

Certificate Object; type = X.509 cert
  label:
  subject:    DN: DC=com, DC=example, CN=example-CA
  ID:         636e3d736173636572742d63612c64633d233136303737333631373336333635373237342c64633d2331363032366636392f636e3d736173636572742d63612c64633d233136303737333631373336333635373237342c64633d2331363032366636392f3332333331303437363031363137343435323138303332383239393236343439353035313332

I could delete the private key and the certificates in Java this way:

if (keyStore.containsAlias("WorkstationAuthentication")) {
    keyStore.deleteEntry("WorkstationAuthentication");
}

pkcs11-tool shows that the private key and the certificates are deleted but the public key has remained on the token:

# pkcs11-tool --module /usr/lib/x86_64-linux-gnu/pkcs11/libtpm2_pkcs11.so --slot-index=0 --list-objects --login
Using slot with index 0 (0x1)
Logging in to "myfirsttoken".
Please enter User PIN:

Public Key Object; RSA 2048 bits
  label:
  Usage:      encrypt, verify
  Access:     local

I could not find any method in Java whose purpose is to delete this public key. And what is more interesting, as we can see in the output of pkcs11-tool, neither the label nor the ID has any value so even if there existed any method whose purpose is to delete a public key we could not identify the public key.

I could delete the public key with pkcs11-tool but I would like to delete it in Java.

So, how can someone delete a public key from a token in Java? Or how can someone prevent the public key to be stored on the token? If I know correctly there is no point in storing the public key on the token because the certificate contains the public key.

Upvotes: 1

Views: 201

Answers (1)

always_a_rookie
always_a_rookie

Reputation: 4830

It is not possible to delete the PublicKey objects from a hardware token using Java's KeyStore Provider.

If you look at the KeyStore class below (Java 17 here, or even other lower versions):

Eclipse IDE screenshot of Java's KeyStore class

There are only 3 types of Entry classifications, namely:

  1. PrivateKeyEntry (Private Key Object + Certificate Object(s))
  2. SecretKeyEntry (Secret Key Object)
  3. TrustedCertificateEntry (Certificate Object)

PublicKey is not one of them. And also look at the methods it offers on the entry types it supports.

So, basically, you cannot handle/manage these PublicKey objects using the KeyStore Provider. If you really need to handle these objects yourself, you can achieve this using the PKCS#11 Wrapper. Using the Wrapper gives you granular control over everything, including the attributes set on an Object during creation, and much more.

Upvotes: 1

Related Questions