我正在尝试使用Java实现RSA-OAEP加密。我了解这需要标签,默认情况下为空字符串。如何使用内置类更改label的值并提供我选择的值?
正如我在评论中所建议的,您需要使用PSource.PSpecified
构造函数。
单词的选择,尤其是变量P
不存在的in the PKCS#1 specifications anywhere会使用户陷入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)); }
顺便说一句,如果您的IDE不知道如何查找,以上当然会使用
import static StandardCharsets.US_ASCII;
。
注意,PKCS#1似乎只允许使用空(八位字节)字符串作为标签,其他使用它超出PKCS#1 v2.2的范围]:
RSAES-OAEP的加密操作需要标签
L
的值作为输入。在此版本的PKCS#1中,L
为空字符串;标签的其他用途不在该文档。因此,使用空字符串以外的任何
L
会将您置于OAEP的标准用法范围之外,您必须自己明确定义此类用法。如果您有某种标识符,则最好将其编码为纯文本消息,因为库可能不支持空字符串以外的标签。最后,关于术语的使用方式和实际的ASN.1定义,有些含糊不清:
pSourceAlgorithm
标识源(可能是值)标签L
。它应该是一个算法ID,在集合中具有OIDPKCS1PSourceAlgorithms
,此版本应包含id-pSpecified
,表示已明确指定标签。与id-pSpecified
关联的参数字段应具有一个类型OCTET STRING
的值,包含标签。在以前在本规范的版本中,术语“编码参数”为使用而不是“标签”,因此是以下类型的名称。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
称为单独变量之外。