海关加签用的ukey加签方式,拼接报文
public class SignHelper ? ? { ? ? ? ? private const int REQUEST_TIME_WAIT = 200; ? ? ? ? private const int TIME_OUT = 60000; ? ? ? ? private const string URL = "ws://127.0.0.1:61232"; ? ? ? ? private static int m_lastRequestTime; ? ? ? ? private static readonly object m_lockThis = new object();
? ? ? ? public static State WebSocketSign(string jsonParamStr) ? ? ? ? { ? ? ? ? ? ? lock (m_lockThis) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? if (Environment.TickCount - m_lastRequestTime < REQUEST_TIME_WAIT) ? ? ? ? ? ? ? ? ? ? Thread.Sleep(REQUEST_TIME_WAIT);
? ? ? ? ? ? ? ? m_lastRequestTime = Environment.TickCount; ? ? ? ? ? ? }
? ? ? ? ? ? WebSocket websocket = new WebSocket(URL); ? ? ? ? ? ? State state = new State() ? ? ? ? ? ? { ? ? ? ? ? ? ? ? Parameter = jsonParamStr ? ? ? ? ? ? };
? ? ? ? ? ? websocket.Error += new EventHandler<SuperSocket.ClientEngine.ErrorEventArgs>((sender, e) => ? ? ? ? ? ? { ? ? ? ? ? ? ? ? state.NoWait = true; ? ? ? ? ? ? ? ? state.Code = "404"; ? ? ? ? ? ? ? ? state.Message = "Error:" + e.Exception.Message; ? ? ? ? ? ? ? ? state.Data = string.Empty; ? ? ? ? ? ? });
? ? ? ? ? ? websocket.MessageReceived += new EventHandler<MessageReceivedEventArgs>((sender, e) => ? ? ? ? ? ? { ? ? ? ? ? ? ? ? try ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? state.Message = "Success"; ? ? ? ? ? ? ? ? ? ? state.Data = e.Message; ? ? ? ? ? ? ? ? ? ? Websocket_MessageReceived(websocket, state); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? catch (Exception ex) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? websocket.Close(); ? ? ? ? ? ? ? ? ? ? websocket.Dispose();
? ? ? ? ? ? ? ? ? ? state.NoWait = true; ? ? ? ? ? ? ? ? ? ? state.Code = "404"; ? ? ? ? ? ? ? ? ? ? state.Message = "Error:" + ex.Message; ? ? ? ? ? ? ? ? ? ? state.Data = string.Empty; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? });
? ? ? ? ? ? websocket.Open();
? ? ? ? ? ? int time = Environment.TickCount;
? ? ? ? ? ? while (!state.NoWait && Environment.TickCount - time < TIME_OUT) ? ? ? ? ? ? ? ? Thread.Sleep(1);
? ? ? ? ? ? websocket.Close(); ? ? ? ? ? ? websocket.Dispose(); ? ? ? ? ? ? state.Code = "200";
? ? ? ? ? ? if (Environment.TickCount - time > TIME_OUT) ? ? ? ? ? ? ? ? state.Message = "request time out.";
? ? ? ? ? ? return state; ? ? ? ? }
? ? ? ? private static void Websocket_MessageReceived(WebSocket webSocket, State state) ? ? ? ? { ? ? ? ? ? ? if (state.Data.Contains("握手成功")) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? StringBuilder postJson = new StringBuilder();
? ? ? ? ? ? ? ? postJson.Append(state.Parameter);
? ? ? ? ? ? ? ? JObject jObject = new JObject ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? ["_method"] = "cus-sec_SpcSignDataAsPEM", ? ? ? ? ? ? ? ? ? ? ["_id"] = 1 ? ? ? ? ? ? ? ? };
? ? ? ? ? ? ? ? JObject args = new JObject ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? ["inData"] = postJson.ToString(), ? ? ? ? ? ? ? ? ? ? ["passwd"] = "88888888" ? ? ? ? ? ? ? ? };
? ? ? ? ? ? ? ? jObject["args"] = args;
? ? ? ? ? ? ? ? webSocket.Send(jObject.ToString()); ? ? ? ? ? ? } ? ? ? ? ? ? else ? ? ? ? ? ? { ? ? ? ? ? ? ? ? state.Data = JObject.Parse(state.Data)["_args"].ToString(); ? ? ? ? ? ? ? ? state.NoWait = true; ? ? ? ? ? ? } ? ? ? ? }
? ? ? ? public static string GetSignature(string dataString) ? ? ? ? { ? ? ? ? ? ? string canonicalizeXmlData = Canonicalize(dataString);
? ? ? ? ? ? SHA1 sha = new SHA1CryptoServiceProvider(); ? ? ? ? ? ? string digest = Convert.ToBase64String(sha.ComputeHash(Encoding.UTF8.GetBytes(canonicalizeXmlData)));
? ? ? ? ? ? string signedInfoContent = GetSignedInfoContent(digest); ? ? ? ? ? ? string signedInfoContentPlus = Canonicalize(GetSignedInfoContentPlus(digest));
? ? ? ? ? ? State state = WebSocketSign(signedInfoContentPlus); ? ? ? ? ? ? JObject jObject = JObject.Parse(state.Data); ? ? ? ? ? ? JArray jArray = jObject["Data"].ToObject<JArray>(); ? ? ? ? ? ? string keyName = jArray[1].ToString(); ? ? ? ? ? ? string signatureValue = jArray[0].ToString(); ? ? ? ? ? ? string signatureXml = ComposeW3cEnvelopedSignedInfoXml(signedInfoContent, signatureValue, keyName, Convert.ToBase64String(Encoding.UTF8.GetBytes(canonicalizeXmlData)));
? ? ? ? ? ? return ComposeW3cEnvelopedXmlEx(signatureXml, canonicalizeXmlData); ? ? ? ? }
? ? ? ? private static string GetSignedInfoContentPlus(string digest) ? ? ? ? { ? ? ? ? ? ? StringBuilder stringBuilder = new StringBuilder(); ? ? ? ? ? ? stringBuilder.Append("<ds:SignedInfo xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\"").Append(" xmlns:ceb=\"http://www.chinaport.gov.cn/ceb\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"").Append(">"); ? ? ? ? ? ? stringBuilder.Append("<ds:CanonicalizationMethod Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/>"); ? ? ? ? ? ? stringBuilder.Append("<ds:SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\"/>"); ? ? ? ? ? ? stringBuilder.Append("<ds:Reference URI=\"\">"); ? ? ? ? ? ? stringBuilder.Append("<ds:Transforms><ds:Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature\"/></ds:Transforms>"); ? ? ? ? ? ? stringBuilder.Append("<ds:DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/>"); ? ? ? ? ? ? stringBuilder.Append("<ds:DigestValue>"); ? ? ? ? ? ? stringBuilder.Append(digest); ? ? ? ? ? ? stringBuilder.Append("</ds:DigestValue></ds:Reference></ds:SignedInfo>"); ? ? ? ? ? ? return stringBuilder.ToString(); ? ? ? ? }
? ? ? ? private static string GetSignedInfoContent(string digest) ? ? ? ? { ? ? ? ? ? ? StringBuilder stringBuilder = new StringBuilder();
? ? ? ? ? ? stringBuilder.Append("<ds:SignedInfo>"); ? ? ? ? ? ? stringBuilder.Append("<ds:CanonicalizationMethod Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/>"); ? ? ? ? ? ? stringBuilder.Append("<ds:SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\"/>"); ? ? ? ? ? ? stringBuilder.Append("<ds:Reference URI=\"\">"); ? ? ? ? ? ? stringBuilder.Append("<ds:Transforms><ds:Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature\"/></ds:Transforms>"); ? ? ? ? ? ? stringBuilder.Append("<ds:DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/>"); ? ? ? ? ? ? stringBuilder.Append("<ds:DigestValue>"); ? ? ? ? ? ? stringBuilder.Append(digest); ? ? ? ? ? ? stringBuilder.Append("</ds:DigestValue></ds:Reference></ds:SignedInfo>"); ? ? ? ? ? ? return stringBuilder.ToString(); ? ? ? ? }
? ? ? ? public static string Canonicalize(string xmlData) ? ? ? ? { ? ? ? ? ? ? XmlDocument xmlDocument = new XmlDocument(); ? ? ? ? ? ? xmlDocument.PreserveWhitespace = true; ? ? ? ? ? ? xmlDocument.LoadXml(xmlData);
? ? ? ? ? ? using (MemoryStream memoryStream = new MemoryStream()) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? using (XmlWriter xmlWriter = XmlWriter.Create(memoryStream)) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? xmlDocument.WriteTo(xmlWriter); ? ? ? ? ? ? ? ? ? ? xmlWriter.Flush(); ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? memoryStream.Position = 0L; ? ? ? ? ? ? ? ? XmlDsigC14NTransform xmlDsigC14NTransform = new XmlDsigC14NTransform(); ? ? ? ? ? ? ? ? xmlDsigC14NTransform.LoadInput(memoryStream);
? ? ? ? ? ? ? ? using (MemoryStream transformMemoryStream = (MemoryStream)xmlDsigC14NTransform.GetOutput(typeof(Stream))) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? return Encoding.UTF8.GetString(transformMemoryStream.ToArray()); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? }
? ? ? ? private static string ComposeW3cEnvelopedSignedInfoXml(string signedInfo, string signatureValue, string keyName, string x509Data) ? ? ? ? { ? ? ? ? ? ? StringBuilder stringBuilder = new StringBuilder(); ? ? ? ? ? ? stringBuilder.Append("<ds:Signature xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\">"); ? ? ? ? ? ? stringBuilder.Append(signedInfo); ? ? ? ? ? ? stringBuilder.Append("<ds:SignatureValue>"); ? ? ? ? ? ? stringBuilder.Append(signatureValue); ? ? ? ? ? ? stringBuilder.Append("</ds:SignatureValue>"); ? ? ? ? ? ? stringBuilder.Append("<ds:KeyInfo><ds:KeyName>"); ? ? ? ? ? ? stringBuilder.Append(keyName); ? ? ? ? ? ? stringBuilder.Append("</ds:KeyName>"); ? ? ? ? ? ? stringBuilder.Append("</ds:KeyInfo>"); ? ? ? ? ? ? stringBuilder.Append("</ds:Signature>"); ? ? ? ? ? ? return stringBuilder.ToString(); ? ? ? ? }
? ? ? ? private static string ComposeW3cEnvelopedXmlEx(string signatureXml, string srcData) ? ? ? ? { ? ? ? ? ? ? int num = srcData.LastIndexOf("</"); ? ? ? ? ? ? return string.Format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>{0}{1}{2}", srcData.Substring(0, num), signatureXml, srcData.Substring(num)); ? ? ? ? }
? ? ? ? private static readonly XmlSerializer m_serializer; ? ? ? ? private static readonly XmlSerializer m_serializerSignature;
? ? ? ? static SignHelper() ? ? ? ? { ? ? ? ? ? ? m_serializer = new XmlSerializer(typeof(SignedInfoType)); ? ? ? ? ? ? m_serializerSignature = new XmlSerializer(typeof(SignatureType)); ? ? ? ? } ? ? ? ? public static string ADDSignature(string dataString, bool isKeyInfo = false) ? ? ? ? { ? ? ? ? ? ? string canonicalizeXmlData = dataString;
? ? ? ? ? ? SHA1 sha = new SHA1CryptoServiceProvider(); ? ? ? ? ? ? string digest = Convert.ToBase64String(sha.ComputeHash(Encoding.UTF8.GetBytes(canonicalizeXmlData)));
? ? ? ? ? ? SignedInfoType signedInfo = GetSignedInfo(digest);
? ? ? ? ? ? StringBuilder stringBuilder = new StringBuilder(); ? ? ? ? ? ? XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces(); ? ? ? ? ? ? namespaces.Add("ceb", "http://www.chinaport.gov.cn/ceb"); ? ? ? ? ? ? namespaces.Add("ds", "http://www.w3.org/2000/09/xmldsig#"); ? ? ? ? ? ? namespaces.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance"); ? ? ? ? ? ? string xmlValue = string.Empty; ? ? ? ? ? ? using (StringWriter stringWriter = new StringWriter(stringBuilder)) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? m_serializer.Serialize(stringWriter, signedInfo, namespaces); ? ? ? ? ? ? ? ? xmlValue = stringWriter.ToString(); ? ? ? ? ? ? }
? ? ? ? ? ? State state = WebSocketSign(xmlValue); ? ? ? ? ? ? JObject jObject = JObject.Parse(state.Data); ? ? ? ? ? ? JArray jArray = jObject["Data"].ToObject<JArray>();
? ? ? ? ? ? string keyName = null;
? ? ? ? ? ? if (isKeyInfo) ? ? ? ? ? ? ? ? keyName = jArray[1].ToString();
? ? ? ? ? ? string signatureValue = jArray[0].ToString();
? ? ? ? ? ? SignatureType signature = GetSignature(signedInfo, signatureValue, keyName);
? ? ? ? ? ? StringBuilder signatureStringBuilder = new StringBuilder(); ? ? ? ? ? ? XmlSerializerNamespaces signatureNamespaces = new XmlSerializerNamespaces(); ? ? ? ? ? ? namespaces.Add("ds", "http://www.w3.org/2000/09/xmldsig#"); ? ? ? ? ? ? string signatureXmlValue = string.Empty; ? ? ? ? ? ? using (StringWriter stringWriter = new StringWriter(signatureStringBuilder)) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? m_serializerSignature.Serialize(stringWriter, signature, signatureNamespaces); ? ? ? ? ? ? ? ? signatureXmlValue = stringWriter.ToString(); ? ? ? ? ? ? }
? ? ? ? ? ? return signatureXmlValue; ? ? ? ? }
? ? ? ? public static SignedInfoType GetSignedInfo(string digest) ? ? ? ? { ? ? ? ? ? ? SignedInfoType signedInfo = new SignedInfoType(); ? ? ? ? ? ? signedInfo.CanonicalizationMethod = new CanonicalizationMethodType(); ? ? ? ? ? ? signedInfo.SignatureMethod = new SignatureMethodType();
? ? ? ? ? ? ReferenceType reference = new ReferenceType();
? ? ? ? ? ? TransformType transform = new TransformType(); ? ? ? ? ? ? reference.Transforms = new TransformType[] { transform }; ? ? ? ? ? ? reference.DigestMethod = new DigestMethodType();
? ? ? ? ? ? reference.DigestValue = Encoding.UTF8.GetBytes(digest);
? ? ? ? ? ? signedInfo.Reference = new ReferenceType[] { reference };
? ? ? ? ? ? return signedInfo; ? ? ? ? }
? ? ? ? private static SignatureType GetSignature(SignedInfoType signedInfo, string signatureValue, string keyName = null) ? ? ? ? { ? ? ? ? ? ? SignatureType signature = new SignatureType();
? ? ? ? ? ? signature.SignedInfo = signedInfo;
? ? ? ? ? ? SignatureValueType signatureValueType = new SignatureValueType();
? ? ? ? ? ? signatureValueType.Value = Encoding.UTF8.GetBytes(signatureValue);
? ? ? ? ? ? signature.SignatureValue = signatureValueType;
? ? ? ? ? ? if (!string.IsNullOrWhiteSpace(keyName)) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? KeyInfoType keyInfo = new KeyInfoType();
? ? ? ? ? ? ? ? keyInfo.ItemsElementName = new ItemsChoiceType2[] { ItemsChoiceType2.KeyName }; ? ? ? ? ? ? ? ? keyInfo.Items = new object[] { keyName };
? ? ? ? ? ? ? ? signature.KeyInfo = keyInfo; ? ? ? ? ? ? }
? ? ? ? ? ? return signature; ? ? ? ? } ? ? }
? ? #region Object
? ? public class JsonParam ? ? { ? ? ? ? public string JsonParamStr { get; set; } ? ? }
? ? public class State ? ? { ? ? ? ? public string Message { get; set; }
? ? ? ? public bool NoWait { get; set; }
? ? ? ? public string Data { get; set; }
? ? ? ? public string Parameter { get; set; }
? ? ? ? public string Code { get; set; } ? ? }
? ? #endregion Object
|