using System; using Renci.SshNet.Common; namespace Renci.SshNet.Security.Cryptography { /// /// Implements digital signature where where asymmetric cipher is used, /// public abstract class CipherDigitalSignature : DigitalSignature { private readonly AsymmetricCipher _cipher; private readonly ObjectIdentifier _oid; /// /// Initializes a new instance of the class. /// /// The object identifier. /// The cipher. protected CipherDigitalSignature(ObjectIdentifier oid, AsymmetricCipher cipher) { if (cipher == null) throw new ArgumentNullException("cipher"); _cipher = cipher; _oid = oid; } /// /// Verifies the signature. /// /// The input. /// The signature. /// /// True if signature was successfully verified; otherwise false. /// public override bool Verify(byte[] input, byte[] signature) { var encryptedSignature = _cipher.Decrypt(signature); var hashData = Hash(input); var expected = DerEncode(hashData); return expected.IsEqualTo(encryptedSignature); } /// /// Creates the signature. /// /// The input. /// /// Signed input data. /// public override byte[] Sign(byte[] input) { // Calculate hash value var hashData = Hash(input); // Calculate DER string var derEncodedHash = DerEncode(hashData); return _cipher.Encrypt(derEncodedHash).TrimLeadingZeros(); } /// /// Hashes the specified input. /// /// The input. /// Hashed data. protected abstract byte[] Hash(byte[] input); /// /// Encodes hash using DER. /// /// The hash data. /// DER Encoded byte array protected byte[] DerEncode(byte[] hashData) { var alg = new DerData(); alg.Write(_oid); alg.WriteNull(); var data = new DerData(); data.Write(alg); data.Write(hashData); return data.Encode(); } } }