使用 Java 为 RSA-OAEP 加密中的标签提供价值
Providing value for label in RSA- OAEP encryption using Java
我正在尝试使用 Java 实施 RSA-OAEP 加密。我知道这需要一个默认为空字符串的标签。如何使用内置 class?
更改标签的值并提供我选择的值
正如我在评论中所建议的,您需要使用 PSource.PSpecified
构造函数。
单词的选择,尤其是变量P
不存在in the PKCS#1 specifications anywhere leads the user into a quagmire of terms in the world of ASN.1 specifications,而不是你想去的地方。
我得出的结论是,Java 设计师/开发人员的意思是 id-pSpecified
,其中 P
就是 EncodedParameters
,这是术语“标签”的旧世界”。这反过来意味着构造函数 PSource.PSpecified
可用于指示(字符编码)标签。因此,尽管术语“标签”可能表示一个字符串,但在密码学领域却不是这样;您必须自己执行某种字符转换,如果您要使用文本标签,则应记录此字符编码。
// 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));
}
顺便说一下,上面当然使用 import static StandardCharsets.US_ASCII;
以防你的 IDE 不知道如何找到它。
请注意,PKCS#1 似乎只允许空(八位字节)字符串作为标签,其他使用它在 PKCS#1 v2.2 的范围之外:
encryption operations of RSAES-OAEP take
the value of a label L
as input. In this version of PKCS #1, L
is
the empty string; other uses of the label are outside the scope of
this document.
因此,使用除空字符串以外的任何 L
会使您超出 OAEP 的标准使用范围,您必须自己明确定义此类用法。如果您有某种标识符,您最好将其编码到明文消息中,因为库可能不支持空字符串以外的标签。
最后,关于这些术语的使用方式和实际的 ASN.1 定义的一些细节:
pSourceAlgorithm
identifies the source (and possibly the value) of
the label L
. It SHALL be an algorithm ID with an OID in the set
PKCS1PSourceAlgorithms
, which for this version SHALL consist of
id-pSpecified
, indicating that the label is specified explicitly.
The parameters field associated with id-pSpecified
SHALL have a
value of type OCTET 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))
这在很大程度上解释了 Java 规范是如何形成的。如果您在阅读规范后考虑它们,它们实际上很有意义 - 当然,除了在规范中将 P
称为单独的变量。
我正在尝试使用 Java 实施 RSA-OAEP 加密。我知道这需要一个默认为空字符串的标签。如何使用内置 class?
更改标签的值并提供我选择的值正如我在评论中所建议的,您需要使用 PSource.PSpecified
构造函数。
单词的选择,尤其是变量P
不存在in the PKCS#1 specifications anywhere leads the user into a quagmire of terms in the world of ASN.1 specifications,而不是你想去的地方。
我得出的结论是,Java 设计师/开发人员的意思是 id-pSpecified
,其中 P
就是 EncodedParameters
,这是术语“标签”的旧世界”。这反过来意味着构造函数 PSource.PSpecified
可用于指示(字符编码)标签。因此,尽管术语“标签”可能表示一个字符串,但在密码学领域却不是这样;您必须自己执行某种字符转换,如果您要使用文本标签,则应记录此字符编码。
// 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));
}
顺便说一下,上面当然使用 import static StandardCharsets.US_ASCII;
以防你的 IDE 不知道如何找到它。
请注意,PKCS#1 似乎只允许空(八位字节)字符串作为标签,其他使用它在 PKCS#1 v2.2 的范围之外:
encryption operations of RSAES-OAEP take the value of a label
L
as input. In this version of PKCS #1,L
is the empty string; other uses of the label are outside the scope of this document.
因此,使用除空字符串以外的任何 L
会使您超出 OAEP 的标准使用范围,您必须自己明确定义此类用法。如果您有某种标识符,您最好将其编码到明文消息中,因为库可能不支持空字符串以外的标签。
最后,关于这些术语的使用方式和实际的 ASN.1 定义的一些细节:
pSourceAlgorithm
identifies 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-pSpecified
SHALL 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))
这在很大程度上解释了 Java 规范是如何形成的。如果您在阅读规范后考虑它们,它们实际上很有意义 - 当然,除了在规范中将 P
称为单独的变量。