1

私はプロジェクトに取り組んでいます。クライアントには共通の認証システムがあります。Web サーバーからノンスを生成し、認証システムの公開鍵を使用して暗号化し、Web サーバーの秘密鍵を使用して歌い、認証システム (XML base64 エンコード) に投稿する必要があります。認証システムは、秘密鍵を使用して復号化し、公開鍵を使用してナンス暗号を生成し、応答として Web サーバーに送り返します。私のウェブサーバーは、私の秘密鍵を使用して応答を復号化します。次のステップは、KDF2 アルゴリズムに基づいて nonce (クライアント) と nonce(サーバー) を使用して sessionKey を構築することです。私はasp.net 4.0を使用しています.. asp.netの「KDF2に基づくノンス(クライアント)とノンス(サーバー)を使用したセッションキー」に関するヘルプを理解して見つけることができません 。

    protected void ButtonLogin_Click()
    {
        string datatopost = CreatEncryptandSignXML();
        PostxmltoCommongateway(datatopost);
    }

    public string CreatEncryptandSignXML()
    {
        string ClientNonce = null;
        ClientNonce = Guid.NewGuid().ToString("N");
        Session["ClientNonce"] = ClientNonce;

        byte[] bytesToEncode = Encoding.UTF8.GetBytes(ClientNonce);

        string encodednonce = Convert.ToBase64String(bytesToEncode);

        string xml = "<?xml version=\"1.0\"?><root><LoginRequest>Nonce=" + encodednonce + "</LoginRequest></root>";
        System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
        doc.LoadXml(xml);
        doc.PreserveWhitespace = true;

        // Sing XML using private key ------------------------------------------------------------
        System.Security.Cryptography.X509Certificates.X509Certificate2 commonauthpublickey =
            new System.Security.Cryptography.X509Certificates.X509Certificate2
                (@"C:\commonauthserver\publickey\sample.cer");

        System.Xml.XmlElement elementToEncrypt = doc.GetElementsByTagName("LoginRequest")[0] as System.Xml.XmlElement;

        System.Security.Cryptography.Xml.EncryptedXml encXML = new System.Security.Cryptography.Xml.EncryptedXml();
        System.Security.Cryptography.Xml.EncryptedData data = encXML.Encrypt(elementToEncrypt, commonauthpublickey);

        System.Security.Cryptography.Xml.EncryptedXml.ReplaceElement(elementToEncrypt, data, false);


        // Sign XML using Private Key ---------------------------------------------------------------

        System.Security.Cryptography.X509Certificates.X509Certificate2 mywerbserverprivatekey =
            new System.Security.Cryptography.X509Certificates.X509Certificate2
                (@"C:\mywebserver\privatekey\mywebserver.pfx","samplepasword");

        System.Security.Cryptography.Xml.SignedXml sign = new System.Security.Cryptography.Xml.SignedXml(doc);

        System.Security.Cryptography.Xml.KeyInfo keyInfo = new System.Security.Cryptography.Xml.KeyInfo();
        sign.SigningKey = mywerbserverprivatekey.PrivateKey;
        System.Security.Cryptography.Xml.KeyInfoX509Data keyInfoData = new System.Security.Cryptography.Xml.KeyInfoX509Data();
        keyInfoData.AddIssuerSerial(mywerbserverprivatekey.Issuer, mywerbserverprivatekey.GetSerialNumberString());
        keyInfo.AddClause(keyInfoData);
        sign.KeyInfo = keyInfo;
        System.Security.Cryptography.Xml.Reference reference = new System.Security.Cryptography.Xml.Reference();
        reference.Uri = "";
        System.Security.Cryptography.Xml.XmlDsigEnvelopedSignatureTransform env = new
            System.Security.Cryptography.Xml.XmlDsigEnvelopedSignatureTransform();
        reference.AddTransform(env);
        sign.AddReference(reference);
        sign.ComputeSignature();
        System.Xml.XmlElement signedElement = sign.GetXml();
        signedElement.Prefix = "ds";
        doc.DocumentElement.AppendChild(signedElement);
        return doc.InnerXml;
    }

    void PostxmltoCommongateway(string encData)
    {
        string URLAuth = "http://commonauth.com/getway/commomauth.do";

        byte[] bytesToEncode = Encoding.UTF8.GetBytes(encData);
        string encodedText = Convert.ToBase64String(bytesToEncode);
        string encodedXML = HttpUtility.UrlEncode(encodedText);

        string postString = string.Format("encryptedData={0}", encodedXML);

        const string contentType = "application/x-www-form-urlencoded";
        System.Net.ServicePointManager.Expect100Continue = false;

        CookieContainer cookies = new CookieContainer();
        HttpWebRequest webRequest = WebRequest.Create(URLAuth) as HttpWebRequest;
        webRequest.Method = "POST";
        webRequest.ContentType = contentType;
        webRequest.CookieContainer = cookies;
        webRequest.ContentLength = postString.Length;
        webRequest.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1";
        webRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
        StreamWriter requestWriter = new StreamWriter(webRequest.GetRequestStream());
        requestWriter.Write(postString);
        requestWriter.Close();

        try
        {
            WebResponse response = webRequest.GetResponse();
            StreamReader responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream());
            string responseData = responseReader.ReadToEnd();
            responseReader.Close();
            webRequest.GetResponse().Close();

            string servernonce = DecryptResponse(responseData);
            string clientnonce = Session["ClientNonce"].ToString();

            /// here i have to generate a sessionKey using nonce (client) and nonce(server) based on KDF2

            // CreateSessionkeybasedonKDF2(servernonce,clientnonce)                
        }

        catch (Exception ex)
        {
            LabelMessage.Text = ex.Message;
        }
    }

public string DecryptResponse(string response)
{
    System.Security.Cryptography.X509Certificates.X509Certificate2 mywerbserverprivatekey =
        new System.Security.Cryptography.X509Certificates.X509Certificate2
            (@"C:\mywebserver\privatekey\mywebserver.pfx", "samplepasword");

    RSACryptoServiceProvider.UseMachineKeyStore = false;
    RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)mywerbserverprivatekey.PrivateKey;
    byte[] decrypted = rsa.Decrypt(Convert.FromBase64String(response), false);
    return ASCIIEncoding.UTF8.GetString(decrypted);

}

事前にご回答いただきありがとうございます。

4

1 に答える 1

0

KDF2 はキー シード (任意の長さ、十分なエントロピーを持つキーを表す必要があります) で、値 1 から始まる BigEndian 表記の 4 バイトのカウンター値が後置されます。つまりKEY_SEED|00000001、最初のキーになります。連結後、値は SHA-1 などの安全なハッシュ アルゴリズムを使用してハッシュされます (使用されるハッシュは構成可能です)。次に、結果のハッシュ値から必要な左端の Xビットまたはバイトを取得します。

KDF2 は暗号化 API には含まれていないことが多いため、KDF2 の実装方法のみを説明できます。残念ながら、実装とテストを自分で行う必要があります (とにかく「ローカライズされすぎている」)。

于 2013-02-17T11:49:03.180 に答える