有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!


共 (1) 个答案

  1. # 1 楼答案

    正如我在评论中所建议的,您需要使用PSource.PSpecified构造函数

    词语的选择,尤其是不存在的变量Pin the PKCS#1 specifications anywhere会让用户陷入ASN.1 specifications世界中术语的泥潭,而不是你想去的地方

    我已经得出结论,Java设计器/开发人员的意思是id-pSpecified,其中PEncodedParameters,这是旧世界中术语“标签”的意思。这反过来意味着构造函数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作为单独的变量引用之外