I am trying to implement RSA-OAEP encryption using Java. I understand that this requires a label which is by default an empty string. How do I change the value of label and provide a value of my choice using the built in class?
As I suggested in the comments, you need to use the PSource.PSpecified constructor.
The choice of words and especially the variable P which does not exists in the PKCS#1 specifications anywhere leads the user into a quagmire of terms in the world of ASN.1 specifications, not the place where you want to be.
I've concluded that the Java designers / devs meant id-pSpecified where P is then the EncodedParameters, which is the old world for the term "label". That in turn would mean that the constructor PSource.PSpecified can be used to indicate the (character-encoded) label. So although the term "label" could possibly indicate a string, it doesn't in the world of cryptography; you will have to perform some kind of character conversion yourself, and this character encoding should be documented if you'd were to use a textual label.
// generate a relatively small key for testing
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair kp = kpg.generateKeyPair();
// OAEP spec with label
OAEPParameterSpec spec = new OAEPParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1,
new PSource.PSpecified("label".getBytes(US_ASCII)));
// OAEP spec without label
OAEPParameterSpec specEmpty = new OAEPParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1,
PSource.PSpecified.DEFAULT);
byte[] ct;
{
// encrypt to ciphertext using label
Cipher rsaOAEPEnc = Cipher.getInstance("RSA/ECB/OAEPPadding");
rsaOAEPEnc.init(Cipher.ENCRYPT_MODE, kp.getPublic(), spec);
ct = rsaOAEPEnc.doFinal("owlstead".getBytes(US_ASCII));
}
{
// decrypt with label
Cipher rsaOAEPDec = Cipher.getInstance("RSA/ECB/OAEPPadding");
rsaOAEPDec.init(Cipher.DECRYPT_MODE, kp.getPrivate(), spec);
byte[] pt = rsaOAEPDec.doFinal(ct);
System.out.println(new String(pt, US_ASCII));
}
{
// decrypt without label (fails with an exception)
Cipher rsaOAEPDec = Cipher.getInstance("RSA/ECB/OAEPPadding");
rsaOAEPDec.init(Cipher.DECRYPT_MODE, kp.getPrivate(), specEmpty);
byte[] pt = rsaOAEPDec.doFinal(ct);
System.out.println(new String(pt, US_ASCII));
}
By the way, above of course uses import static StandardCharsets.US_ASCII; in case your IDE doesn't know how to find that.
Note that PKCS#1 only seems to allow empty (octet) strings as label, other use it outside the scope of PKCS#1 v2.2:
encryption operations of RSAES-OAEP take the value of a label
Las input. In this version of PKCS #1,Lis the empty string; other uses of the label are outside the scope of this document.
So using any L other than the empty string places you outside standard use of OAEP and you'll have to explicitly define such usages yourself. If you have some kind of identifier you might be better encoding it into the plaintext message, as libraries may not provide support for labels other than the empty string.
Finally, some nitty-gritty on how the terms are used and the actual ASN.1 definions:
pSourceAlgorithmidentifies the source (and possibly the value) of the labelL. It SHALL be an algorithm ID with an OID in the setPKCS1PSourceAlgorithms, which for this version SHALL consist ofid-pSpecified, indicating that the label is specified explicitly. The parameters field associated withid-pSpecifiedSHALL have a value of typeOCTET STRING, containing the label. In previous versions of this specification, the term "encoding parameters" was used rather than "label", hence the name of the type below.
PSourceAlgorithm ::= AlgorithmIdentifier {
{PKCS1PSourceAlgorithms}
}
PKCS1PSourceAlgorithms ALGORITHM-IDENTIFIER ::= {
{ OID id-pSpecified PARAMETERS EncodingParameters },
... -- Allows for future expansion --
}
id-pSpecified OBJECT IDENTIFIER ::= { pkcs-1 9 }
EncodingParameters ::= OCTET STRING(SIZE(0..MAX))
This largely explains how the Java specifications came to be. They actually make a lot of sense if you regard them after reading the specification - except for referring to P as separate variable within the specification of course.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With