私はこれを成功させました。あまりにも難しくなく、うまくいきます。私はそれを使って製品のライセンスを有効にします。最も重要なことは、あなたが本当にクライアントとサーバーを制御できることです。だれもクライアントのコードから秘密鍵を抽出することはできません。
ステップ1:
[HttpPost] public ActionResult Activate() { ... }
ステップ2:コントローラにだけ、クライアントから送信されたバイトのネタを取得するためにHttpRequest.InputStreamを使用する引数をとらないMVCコントローラのアクションメソッドを作成します。 。
var stream = this.HttpContext.Request.InputStream;
ステップ3:デシリアライズするCryptoStreamを作成します。
ここでは、暗号化と復号化の両方の例を作成しました。 sharedSecretは、十分な長さ(512バイト)のランダムバイトのbyte []です。これはあなたが保護するものです!
public CryptoStream CreateEncryptionStream(Stream writeStream)
{
TripleDESCryptoServiceProvider cryptoProvider = new TripleDESCryptoServiceProvider();
PasswordDeriveBytes derivedBytes = new PasswordDeriveBytes(this._sharedSecret, null);
CryptoStream cryptoStream = new CryptoStream(writeStream, cryptoProvider.CreateEncryptor(derivedBytes.GetBytes(16), derivedBytes.GetBytes(16)), CryptoStreamMode.Write);
return cryptoStream;
}
public CryptoStream CreateDecryptionStream(Stream readStream)
{
TripleDESCryptoServiceProvider cryptoProvider = new TripleDESCryptoServiceProvider();
PasswordDeriveBytes derivedBytes = new PasswordDeriveBytes(this._sharedSecret, null);
CryptoStream cryptoStream = new CryptoStream(readStream, cryptoProvider.CreateDecryptor(derivedBytes.GetBytes(16), derivedBytes.GetBytes(16)), CryptoStreamMode.Read);
return cryptoStream;
}
ステップ4:復号化するために、あなたのCryptoStream別のストリームリーダーを使用してください。
XmlReaderを使用して、既存のすべてのシリアル化コードをクリア(読み取り/書き込み時)または暗号化(送信時)することができます。
using (var reader = XmlReader.Create(decryptionStream, settings)) { ... }
ステップ5:コントローラで安全な応答を作成します。
これは、手順1〜4とは逆に応答オブジェクトを暗号化しています。次に、暗号化されたレスポンスをメモリストリームに書き込み、ファイルの結果として返します。以下、私はライセンス応答オブジェクトのためにこれをどのように行うのかを示しました。
var responseBytes = GetLicenseResponseBytes(licenseResponse);
return File(responseBytes, "application/octet-stream");
private byte[] GetLicenseResponseBytes(LicenseResponse licenseResponse)
{
if (licenseResponse != null)
{
using (MemoryStream memoryStream = new MemoryStream())
{
this._licenseResponseSerializer.Write(memoryStream, licenseResponse);
return memoryStream.ToArray();
}
}
return null;
}
手順6:クライアント要求応答を実装します。
HttpWebRequestまたはWebClientクラスを使用して要求を作成できます。ここでは、私が使用するコードの例をいくつか紹介します。
byte[] postBytes = GetLicenseRequestBytes(licenseRequest);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(licenseServerUrl);
request.Method = "POST";
request.ContentType = "application/octet-stream";
request.Proxy = WebRequest.DefaultWebProxy;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(postBytes, 0, postBytes.Length);
}
return request;
private LicenseResponse ProcessHttpResponse(HttpWebResponse response)
{
if ((response.StatusCode == HttpStatusCode.OK) && response.ContentType.Contains("application/octet-stream"))
{
var stream = response.GetResponseStream();
if (stream != null)
{
var licenseResponse = this._licenseResponseSerializer.Read(stream);
return licenseResponse;
}
}
return new LicenseResponse(LicensingResult.Error);
}
概要とヒント
- バイナリオクテットストリームデータを通信するために、クライアントとサーバー上の要求/応答のストリームを使用し
- 暗号化アルゴリズムと一緒に使用CryptoStream(考えます最も強力な暗号化を使用して)、シリアル化/逆シリアル化するときにデータを暗号化するための秘密鍵が必要です。
- 可能であれば(DeepSea社obfustactorを見てみましょう難読化を使用してクライアント上の秘密鍵を保護
- (バッファオーバーランを回避し、早期に例外をスロー)のサイズをチェックして、クライアントとサーバへのすべての着信データをフォーマットすることを確認します)
SSL/TLSを再発明する?? – Aliostad
問題は、中間攻撃でフィドラーのようなツールを使用している人がいかに簡単かです。 – DannyT