新增一個nodejs的解法。原文關於GPO的設定在本文之後。
最近2020/07月研究了c#調用nodejs,若你的專案可以使用.net 4.5以上,便可以安裝edge.js
交由nodejs來算md5,一樣也不受到FIPS的啟用影響。
直接透過nuget安裝edge.js。
記得引入using EdgeJs;
調用的話
Md5_NodeJs(“Author is so handsome").Wait();
實作
static async Task<string> Md5_NodeJs(string inputStr) {
//引入的md5路徑不一定會與此範例相同,請再自行調整,可將md5.js引入到
//VS專案中,設好相對路徑,便不需像此範例使用絕對路徑了。
//md5版本有些實作的不同!有些是回傳buffer,有些是回傳string
//此範例是回傳是buffer,故要再轉換成string
Func<object, Task<object>> md5func = Edge.Func(@"
return function (data, callback) {
var md5 = require('C:\\Program Files\\nodejs\\node_modules\\npm\\node_modules\\uuid\\lib\\md5.js');
console.log(md5(data));
const md5CalcResult=md5(data);
console.log(typeof md5CalcResult);
md5CalcResultHex=md5CalcResult.toString('hex');
console.log('Nodejs:'+md5CalcResultHex);
callback(null, md5CalcResultHex);
}");
string md5ResultStr = (await md5func(inputStr)).ToString();
Console.WriteLine(md5ResultStr);
return md5ResultStr;
}
看一下第一次po這文的時間,…已經4年前了啊。
政府組態基準GCB有一項標準是
系統密碼編譯: 使用 FIPS 140 相容密碼編譯演算法,包括加密、雜湊與簽署演算法
這個功能若開啟,.net平台就不能用md5
C#以及asp,還有IIS都會被限制,而丟出例外
只有.net平台受到限制,java與Python就沒有受到限制了。
可以自己看一下GPO的設定
路徑是 Security Settings/Local Policies/Security Options/
System cryptography: Use FIPS…..
2003 or xp則可以看機碼
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\fipsalgorithmpolicy
是不是被改成1
反組譯.net4.0 的 System.Security.Cryptography.MD5CryptoServiceProvider
可以看見MD5CryptoServiceProvider的建構子
[SecuritySafeCritical]
public MD5CryptoServiceProvider()
{
//就是這個判斷式造成無法用md5的。
if (CryptoConfig.AllowOnlyFipsAlgorithms)
throw new InvalidOperationException(Environment.GetResourceString(“Cryptography_NonCompliantFIPSAlgorithm"));
this._safeHashHandle = Utils.CreateHash(Utils.StaticProvHandle, 32771);
}
.net4可以直接看是否有開啟FIPS的限制,這個屬性是public的
Console.WriteLine(System.Security.Cryptography.CryptoConfig.AllowOnlyFipsAlgorithms);
.net2的話比較煩瑣,要透過叫用NativeCode
[DllImport(“bcrypt.dll")]
internal static extern uint BCryptGetFipsAlgorithmMode(
[MarshalAs(UnmanagedType.U1), Out]out bool pfEnabled);
public static bool IsSecurityOptionsFIPSEnabled
{
get
{
if (Environment.OSVersion.Version.Major >= 6)
{
bool fipsEnabled;
uint policyReadStatus = BCryptGetFipsAlgorithmMode(out fipsEnabled);
return ((policyReadStatus==0) && fipsEnabled);
}
else
{
using (RegistryKey fipsAlgorithmPolicyKey = Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Control\Lsa", false))
{
if (fipsAlgorithmPolicyKey != null)
{
object data = fipsAlgorithmPolicyKey.GetValue(“FIPSAlgorithmPolicy");
if (data != null)
return ((int)data == 1);
}
return false;
}
}
}
}
asp可以改用sha1,但還要在IIS電腦金鑰的地方做調整
或是在web.config的<system.web>屬性間加入一行
<system.web>
<machineKey decryption="3DES" validation="SHA1″ />
</system.web>
但我的工具是要與其它產品溝通,沒辦法要求對方也改sha1
所以我一樣得用md5,也可以先用c++寫成處理md5的dll,再來叫用這dll也算是一種解決方式
不過我是採用GNU on Windows的工具
https://github.com/bmatzelle/gow/wiki
md5sum來處理,有3個檔案要複製到
md5sum.exe、libiconv2.dll、libintl3.dll
把我要處理的字串,先存檔
再透過c#叫用此dos指令來計算md5,再濾掉一些不相干的字元