最近在學習加密解密技術碰到個問題,關于C#的System.String轉換成C++中的char *。
因為我的加解密函式都是標準C寫的,不能改用別的語言寫。但界面又是C#做的,用戶輸入明文,呼叫底層C的加密函式后回傳到C#,再由C#保存到sql server資料庫中,這個程序不能改動,所以搞的編程有點費勁。
一、C#界面中輸入明文
String plaintext = TextBox1.text;
呼叫加密函式:
encrypto(ref plaintext)
通過加密函式將明文傳到C++寫的dll再傳回來。
二、C++寫的資料轉換函式
首先將System::String轉換成char *
char * cplain = (char *)Marshal::StringToHGlobalAnsi(plaintext).ToPointer();
然后再呼叫C寫的加密函式
native_c_encrypto->native_encrypto(cplain, cipher, cplain_sz);
cipher為加密后的密文,再把cipher轉換成C#的String傳回界面中:
plaintext = Marshal::PtrToStringAnsi((IntPtr)(char *)cipher);
三、然后再由C#寫入資料庫,這些程序都沒有問題,資料轉換啊、加密啊、存盤到資料庫中都是正常的。但是再由資料庫中讀取密文,然后解密后在C#界面中顯示就出問題了。
(一)從資料庫中讀取密文能正常讀取到,看讀取的結果也是之前加密后的東西,是亂碼,如字串“helloworld”被加密成“铞獚%?D,”,反正是亂碼。
String ciphertext= TextBox2.text;
解密函式:
decrypto(ref ciphertext)
(二)將“铞獚%?D,”轉換成char *格式,這里就不對了,轉換后的字串通過除錯明顯的跟加密后的字串不一樣,連加解密前后的字串的長度也不一致。我呼叫的加解密演算法是aes-ctr,所以加解密前后的字串的長度應該是一致的。轉換的函式還是:
char * cipher= (char *)Marshal::StringToHGlobalAnsi(ciphertext).ToPointer();
(三)再呼叫C寫的解密函式進行解密,結果肯定不對的,呼叫完后再轉換成C#的String在界面中顯示:
呼叫C寫的解密函式:
native_c_encrypto->native_decrypto(cipher, cplain, cipher_sz);
ciphertext= Marshal::PtrToStringAnsi((IntPtr)(char *)cplain);
顯示的東西就是下面的亂碼:
hellow?,
四、問題分析:
加解密函式應該是沒有問題的,因為我用了純C++撰寫的本地函式進行測驗,測驗的字串helloworld,是可以正常的進行加解密的。所以感覺應該是C++的char *在向C#的String轉換的時候出了問題,因為加密后的字串是亂碼,不能用正常的字符顯示出來。想問下大家有沒有好的解決辦法,不需要正常顯示,只需要在加密完后,然后解密正確就行,同時不能對字串長度有限制,最起碼20個字符內的要沒有問題吧。我測驗的對長度為5的字串加解密沒問題,但超過5個字符解密后就亂了。
謝謝大家!如果解決了,后期再能不能再追加積分。
uj5u.com熱心網友回復:
百度“C# pinvoke 封送字串”提示:
1.stringBuilder
2.字符約定Charset
uj5u.com熱心網友回復:
ps:從資料庫中讀取密文能正常讀取到,看讀取的結果也是之前加密后的東西,是亂碼,如字串“helloworld”被加密成“铞獚%?D,”,反正是亂碼
我想說“這難道不符合你的預期”??“helloworld”被加密成“铞獚%?D,” 是他被加密了,變成了你看不懂的,難道不是加密??我們應該認為“hellowrold”被加密成“hellowrold”才是正常的么?
我們只能說
铞獚%?D, 能不能解密成“hellowrold”才是我們關心的
uj5u.com熱心網友回復:
另外在說一句,des演算法是公開的,純粹試驗上你可以用c++實作,然后用C#呼叫。但是既然是DES演算法公開,那么自然C#里面本來就有DES庫,從專案上你并不需要在用C++做。當然有些人可以說,用C++演算法是我自己的,這樣才安全。不過我們說,任何一本現代密碼學第一句話就應該是“密鑰才是演算法的安全的前提,演算法本身不是”,所以你看到的是“8位密鑰,128位密鑰,256位密鑰,512密鑰”的討論,而不是“XXX演算法的討論”
uj5u.com熱心網友回復:
但即使我先把C#的String轉換成wchar *,然后再轉換成char *,在把資料傳給加密函式的程序沒有問題。但加密完回傳給C#界面的時候就有問題,雖然會提示加密正確,但程式直接就例外崩潰掉了,不會解決。。。頭疼uj5u.com熱心網友回復:
加密串要以binary的方式,或是轉成16進制等價的字串或base64進行保存,否則會造成資訊丟失。比如:
或者
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/226759.html
標籤:C#
上一篇:C# 后臺呼叫介面傳資料
