// VerifyData - plug compatible with RSACryptoServiceProvider.VerifyData public bool VerifyData(byte [] data, HashAlgorithm hasher, byte [] signature) { HASH_ALGORITHM ha = map_hash_algorithm(hasher); byte [] hash = hasher.ComputeHash(data); return(VerifyHash(hash, signature, ha)); }
// SignData - plug compatible with RSACryptoServiceProvider.SignData, // but only this one override provided public byte [] SignData(byte [] data, HashAlgorithm hasher) { HASH_ALGORITHM ha = map_hash_algorithm(hasher); byte [] hash = hasher.ComputeHash(data); byte [] signed_hash = SignHash(hash, ha); return(signed_hash); }
static Global() { VisionSN = string.Empty; IsVisionCamera = false; IS_WOLFCOM = true; GlobalAccount = new Account(); DefaultHashAlgorithm = HASH_ALGORITHM.SHA1; ClassificationDays = new Dictionary <string, int>(); UNCServer = "C:"; RelativePath = "C3Sentinel"; PrimaryUNCServer = "C:"; PrimaryRelativePath = "C3Sentinel"; INIFILE = "CITE.INI"; RightsProfile = 0; Camera_LogRecordID = Guid.Empty; Camera_Battery = 0; Camera_Disk = 0; Camera_FileCount = 0; Camera_SerialNum = string.Empty; }
public static HashAlgorithm GetHashAlgorithm(HASH_ALGORITHM ha) { switch (ha) { case HASH_ALGORITHM.Md5: return(new MD5CryptoServiceProvider()); case HASH_ALGORITHM.Sha1: return(new SHA1Managed()); case HASH_ALGORITHM.Sha256: return(new SHA256Managed()); case HASH_ALGORITHM.Sha384: return(new SHA384Managed()); case HASH_ALGORITHM.Sha512: return(new SHA512Managed()); default: return(new MD5CryptoServiceProvider()); } }
// Verify a signed PKCS#1 message digest public bool VerifyHash(byte[] hash, byte[] signature, HASH_ALGORITHM hash_algorithm) { int sig_len = signature.Length; if (sig_len != this.keylen) return false; byte[] decrypted = DoPublic(signature); if (decrypted[0] != 0 || decrypted[1] != RSA_SIGN) return false; int decrypted_len = decrypted.Length; // = keylen for (int i = 2; i < decrypted_len - 1; ++i) { byte b = decrypted[i]; if (b == 0) // end of padding { ++i; int bytes_left = decrypted_len - i; if (bytes_left == 34) // MDx { if (decrypted[i + 13] != (byte)hash_algorithm) return false; decrypted[i + 13] = 0; if (!compare_bytes(decrypted, i, ASN1_HASH_MDX, 0, 18)) return false; return compare_bytes(decrypted, i + 18, hash, 0, 16); } if (bytes_left == 35 && hash_algorithm == HASH_ALGORITHM.RSA_SHA1) { if (!compare_bytes(decrypted, i, ASN1_HASH_SHA1, 0, 15)) return false; return compare_bytes(decrypted, i + 15, hash, 0, 20); } if (bytes_left == hash.Length && hash_algorithm == HASH_ALGORITHM.RSA_RAW) return compare_bytes(decrypted, i, hash, 0, bytes_left); return false; } if (b != 0xFF) break; } return false; }
// Sign a message digest and pack it up into PKCS#1 format public byte[] SignHash(byte[] sign_me, HASH_ALGORITHM hash_algorithm) { int input_len = sign_me.Length; int n_pad = 0; switch (hash_algorithm) { case HASH_ALGORITHM.RSA_RAW: n_pad = this.keylen - 3 - input_len; break; case HASH_ALGORITHM.RSA_MD2: case HASH_ALGORITHM.RSA_MD4: case HASH_ALGORITHM.RSA_MD5: if (input_len != 16) throw new ArgumentException("MDx hashes must be 16 bytes long"); n_pad = this.keylen - 3 - 34; break; case HASH_ALGORITHM.RSA_SHA1: if (input_len != 20) throw new ArgumentException("SHA1 hashes must be 20 bytes long"); n_pad = this.keylen - 3 - 35; break; } if (n_pad < 8) throw new ArgumentException("input too long"); byte[] encrypt_me = new byte[this.keylen]; encrypt_me[0] = 0; encrypt_me[1] = RSA_SIGN; for (int i = 0; i < n_pad; ++i) encrypt_me[i + 2] = 0xFF; encrypt_me[n_pad + 2] = 0; switch (hash_algorithm) { case HASH_ALGORITHM.RSA_RAW: Array.Copy(sign_me, 0, encrypt_me, n_pad + 3, input_len); break; case HASH_ALGORITHM.RSA_MD2: case HASH_ALGORITHM.RSA_MD4: case HASH_ALGORITHM.RSA_MD5: Array.Copy(ASN1_HASH_MDX, 0, encrypt_me, n_pad + 3, 18); encrypt_me[n_pad + 3 + 13] = (byte)hash_algorithm; Array.Copy(sign_me, 0, encrypt_me, n_pad + 3 + 18, input_len); break; case HASH_ALGORITHM.RSA_SHA1: Array.Copy(ASN1_HASH_SHA1, 0, encrypt_me, n_pad + 3, 15); Array.Copy(sign_me, 0, encrypt_me, n_pad + 3 + 15, input_len); break; } return DoPrivate(encrypt_me); }
// Verify a signed PKCS#1 message digest public bool VerifyHash(byte [] hash, byte [] signature, HASH_ALGORITHM hash_algorithm) { int sig_len = signature.Length; if (sig_len != this.keylen) { return(false); } byte [] decrypted = DoPublic(signature); if (decrypted [0] != 0 || decrypted [1] != RSA_SIGN) { return(false); } int decrypted_len = decrypted.Length; // = keylen for (int i = 2; i < decrypted_len - 1; ++i) { byte b = decrypted [i]; if (b == 0) // end of padding { ++i; int bytes_left = decrypted_len - i; if (bytes_left == 34) // MDx { if (decrypted [i + 13] != (byte)hash_algorithm) { return(false); } decrypted [i + 13] = 0; if (!compare_bytes(decrypted, i, ASN1_HASH_MDX, 0, 18)) { return(false); } return(compare_bytes(decrypted, i + 18, hash, 0, 16)); } if (bytes_left == 35 && hash_algorithm == HASH_ALGORITHM.RSA_SHA1) { if (!compare_bytes(decrypted, i, ASN1_HASH_SHA1, 0, 15)) { return(false); } return(compare_bytes(decrypted, i + 15, hash, 0, 20)); } if (bytes_left == hash.Length && hash_algorithm == HASH_ALGORITHM.RSA_RAW) { return(compare_bytes(decrypted, i, hash, 0, bytes_left)); } return(false); } if (b != 0xFF) { break; } } return(false); }
// VerifyHash - plug compatible with RSACryptoServiceProvider.VerifyHash public bool VerifyHash(byte [] hash, string hash_algorithm_oid, byte [] signature) { HASH_ALGORITHM ha = MapHashAlgorithmOID(hash_algorithm_oid); return(VerifyHash(hash, signature, ha)); }
// Sign a message digest and pack it up into PKCS#1 format public byte [] SignHash(byte [] sign_me, HASH_ALGORITHM hash_algorithm) { int input_len = sign_me.Length; int n_pad = 0; switch (hash_algorithm) { case HASH_ALGORITHM.RSA_RAW: n_pad = this.keylen - 3 - input_len; break; case HASH_ALGORITHM.RSA_MD2: case HASH_ALGORITHM.RSA_MD4: case HASH_ALGORITHM.RSA_MD5: if (input_len != 16) { throw new ArgumentException("MDx hashes must be 16 bytes long"); } n_pad = this.keylen - 3 - 34; break; case HASH_ALGORITHM.RSA_SHA1: if (input_len != 20) { throw new ArgumentException("SHA1 hashes must be 20 bytes long"); } n_pad = this.keylen - 3 - 35; break; } if (n_pad < 8) { throw new ArgumentException("input too long"); } byte [] encrypt_me = new byte [this.keylen]; encrypt_me [0] = 0; encrypt_me [1] = RSA_SIGN; for (int i = 0; i < n_pad; ++i) { encrypt_me [i + 2] = 0xFF; } encrypt_me [n_pad + 2] = 0; switch (hash_algorithm) { case HASH_ALGORITHM.RSA_RAW: Array.Copy(sign_me, 0, encrypt_me, n_pad + 3, input_len); break; case HASH_ALGORITHM.RSA_MD2: case HASH_ALGORITHM.RSA_MD4: case HASH_ALGORITHM.RSA_MD5: Array.Copy(ASN1_HASH_MDX, 0, encrypt_me, n_pad + 3, 18); encrypt_me [n_pad + 3 + 13] = (byte)hash_algorithm; Array.Copy(sign_me, 0, encrypt_me, n_pad + 3 + 18, input_len); break; case HASH_ALGORITHM.RSA_SHA1: Array.Copy(ASN1_HASH_SHA1, 0, encrypt_me, n_pad + 3, 15); Array.Copy(sign_me, 0, encrypt_me, n_pad + 3 + 15, input_len); break; } return(DoPrivate(encrypt_me)); }
// SignHash - plug compatible with RSACryptoServiceProvider.SignHash public byte [] SignHash(byte [] sign_me, string hash_algorithm_oid) { HASH_ALGORITHM ha = MapHashAlgorithmOID(hash_algorithm_oid); return(SignHash(sign_me, ha)); }