/// <summary> /// Gets ASN-encoded algorithm identifier based on current configuration. /// </summary> /// <param name="alternate"> /// Specifies whether alternate signature format is used. This parameter has meaning only for /// ECDSA keys. Otherwise, the parameter is ignored. Default value is <strong>false</strong>. /// </param> /// <returns>ASN-encoded algorithm identifier.</returns> public AlgorithmIdentifier GetAlgorithmIdentifier(Boolean alternate = false) { if (SignatureAlgorithm == null) { getSignatureAlgorithm(); } Oid algId = SignatureAlgorithm; List <Byte> parameters = new List <Byte>(); switch (PublicKeyAlgorithm.Value) { case AlgorithmOids.ECC: // ECDSA if (alternate) { // specifiedECDSA algId = new Oid(AlgorithmOids.ECDSA_SPECIFIED); // only here we override algorithm OID parameters .AddRange( new AlgorithmIdentifier(HashingAlgorithm.ToOid(), Asn1Utils.EncodeNull()).RawData ); } break; case AlgorithmOids.RSA: // RSA // only RSA supports parameters. For PKCS1 padding: NULL, for PSS padding: // RSASSA-PSS-params ::= SEQUENCE { // hashAlgorithm [0] HashAlgorithm DEFAULT sha1, // maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1, // saltLength [2] INTEGER DEFAULT 20, // trailerField [3] TrailerField DEFAULT trailerFieldBC // } if (PaddingScheme == SignaturePadding.PSS) { Byte[] hash = new AlgorithmIdentifier(HashingAlgorithm.ToOid(), null).RawData; parameters.AddRange(Asn1Utils.Encode(hash, 0xa0)); // mask generation function: mgf1 Byte[] mgf = new AlgorithmIdentifier(new Oid("1.2.840.113549.1.1.8"), hash).RawData; parameters.AddRange(Asn1Utils.Encode(mgf, 0xa1)); // salt parameters.AddRange(Asn1Utils.Encode(new Asn1Integer(20).RawData, 0xa2)); // general PSS parameters encode parameters = new List <Byte>(Asn1Utils.Encode(parameters.ToArray(), 48)); } else { parameters.AddRange(Asn1Utils.EncodeNull()); } break; } return(new AlgorithmIdentifier(algId, parameters.ToArray())); }