// Calculate MD5 by Windows CryptoAPI |
// |
// Using CryptAcquireContext |
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa382375%28v=vs.85%29.aspx |
#include<windows.h> |
#include<tchar.h> |
#include<stdio.h> |
#include<memory> |
#include<vector> |
structMd5 { |
BYTE data[16]; |
}; |
structCryptProv { |
CryptProv(LPCTSTR pszContainer, LPCTSTR pszProvider, DWORD dwProvType, DWORD dwFlags) { |
CryptAcquireContext(&hCryptProv, pszContainer, pszProvider, dwProvType, dwFlags); |
} |
~CryptProv() { |
if(hCryptProv) { |
CryptReleaseContext(hCryptProv, 0); |
} |
} |
HCRYPTPROV get() const { |
return hCryptProv; |
} |
HCRYPTPROV hCryptProv {}; |
}; |
structCryptHash { |
CryptHash(HCRYPTPROV hCryptProv, ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags) { |
CryptCreateHash(hCryptProv, Algid, hKey, dwFlags, &hCryptHash); |
} |
~CryptHash() { |
if(hCryptHash) { |
CryptDestroyHash(hCryptHash); |
} |
} |
HCRYPTHASH get() const { |
return hCryptHash; |
} |
HCRYPTHASH hCryptHash {}; |
}; |
Md5 calcFileMd5(const TCHAR* filename) { |
Md5 md5{}; |
std::unique_ptr<void, decltype(&CloseHandle)> hFile( |
CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr) |
, CloseHandle |
); |
if(hFile.get() INVALID_HANDLE_VALUE) { |
return md5; |
} |
CryptProv cryptProv{nullptr, nullptr, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT}; |
if(!cryptProv.get()) { |
return md5; |
} |
CryptHash cryptHash{cryptProv.get(), CALG_MD5, 0, 0}; |
if(!cryptHash.get()) { |
return md5; |
} |
std::vector<BYTE> buf(65536); |
DWORD readBytes {}; |
while(ReadFile(hFile.get(), buf.data(), buf.size(), &readBytes, nullptr) && readBytes) { |
if(!CryptHashData(cryptHash.get(), buf.data(), readBytes, 0)) { |
break; |
} |
} |
Md5 tmp{}; |
DWORD md5Bytes = static_cast<DWORD>(sizeof(tmp.data)); |
if(!CryptGetHashParam(cryptHash.get(), HP_HASHVAL, tmp.data, &md5Bytes, 0)) { |
return md5; |
} |
md5 = tmp; |
return md5; |
} |
int_tmain(int argc, TCHAR* argv[]) { |
for(int i = 0; i < argc; ++i) { |
constauto md5 = calcFileMd5(argv[i]); |
_tprintf(_T('MD5 (%s) = '), argv[i]); |
for(auto j = 0u; j < sizeof(md5.data); ++j) { |
_tprintf(_T('%02x'), md5.data[j]); |
} |
_tprintf(_T('n')); |
} |
} |
Password Encryption. Strong password encryption provides an early barrier against attack. Solaris software provides four password encryption algorithms. The two MD5 algorithms and the Blowfish algorithm provide more robust password encryption than the UNIX algorithm. Password Algorithm Identifiers. MD5 was designed by Ronald Rivest in 1991 to replace an earlier hash function MD4, and was specified in 1992 as RFC 1321. One basic requirement of any cryptographic hash function is that it should be computationally infeasible to find two distinct messages that hash to the same value. MD5 hashes are also used to ensure the data integrity of files. Because the MD5 hash algorithm always produces the same output for the same given input, users can compare a hash of the source file with a newly created hash of the destination file to check that it is intact and unmodified.
Anyone who has access to the database can attempt to INSERT duplicate values to a primary key. Cannot use identity column key generation with union-subclass mapping for. What an identity does is make it easier to generate unique values (especially if you do not have a good natural key as Kenneth Fisher says). But neither does anything else.