我正在开展一个项目。客户端有共同的认证系统。我必须从我的Web服务器生成一个nonce,使用身份验证系统的公钥进行加密,然后使用我的webserver私钥进行唱歌并发布到身份验证系统(XML base64编码)。身份验证系统使用其私钥解密,使用我的公钥生成随机数加密,并作为响应发送回我的网络服务器。我的网络服务器使用我的私钥解密响应。 现在,下一步是使用基于KDF2算法的nonce(客户端)和nonce(服务器)构造sessionKey。我正在使用asp.net 4.0 ..无法理解并在asp.net中使用基于KDF2“的nonce(客户端)和nonce(服务器)”sessionKey找到任何类型的帮助。
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);
}
感谢您提前回复。
答案 0 :(得分:0)
KDF2是关键种子(任何长度,应该代表具有足够熵的密钥),后缀为BigEndian表示法中的4字节计数器值,从值1开始。因此对于第一个键,这将是KEY_SEED|00000001
。在连接之后,使用像SHA-1这样的安全散列算法对值进行散列(要使用的散列是可配置的)。然后从生成的哈希值中获取所需的X 最左侧位或字节。
我只能告诉你如何实现KDF2,因为它通常不包含在加密API中,我担心你必须自己进行实施和测试(无论如何都是“过于本地化”)。