private static void TcpProcessMessage(BinaryReader br) { if (br.ReadByte() != 1) { Debug.Assert(false); return; } int cb = MemUtil.BytesToInt32(br.ReadBytes(4)); if ((cb <= 0) || (cb > IpcTcpMsgSizeMax)) { Debug.Assert(false); return; } byte[] pbEnc = br.ReadBytes(cb); if ((pbEnc == null) || (pbEnc.Length != cb)) { Debug.Assert(false); return; } const int cbID = (int)PwUuid.UuidSize; byte[] pb = CryptoUtil.UnprotectData(pbEnc, IpcTcpOptEnt, DataProtectionScope.CurrentUser); if ((pb == null) || (pb.Length != (cbID + 8 + 4 + 4))) { Debug.Assert(false); return; } PwUuid puID = new PwUuid(MemUtil.Mid(pb, 0, cbID)); foreach (KeyValuePair <PwUuid, DateTime> kvp in g_lOldMsgs) { if (puID.Equals(kvp.Key)) { Debug.Assert(false); return; } } DateTime dtNow = DateTime.UtcNow, dtMsg = DateTime.FromBinary( MemUtil.BytesToInt64(pb, cbID)); if ((dtNow - dtMsg).TotalMilliseconds > IpcTcpTtlMs) { Debug.Assert(false); return; } g_lOldMsgs.Add(new KeyValuePair <PwUuid, DateTime>(puID, dtMsg)); int iMsg = MemUtil.BytesToInt32(pb, cbID + 8); int lParam = MemUtil.BytesToInt32(pb, cbID + 8 + 4); MainForm mf = Program.MainForm; VoidDelegate f = delegate() { try { mf.ProcessAppMessage(new IntPtr(iMsg), new IntPtr(lParam)); } catch (Exception) { Debug.Assert(false); } }; mf.Invoke(f); }
public ServerDomainDnsData GetOrCreateUnusedDnsData(IDaoFactory daoFactory, Entities.Server server) { var serverDnsDao = daoFactory.CreateServerDnsDao(Tenant, User); var dnsSettings = serverDnsDao.GetFree(); if (dnsSettings == null) { string privateKey, publicKey; CryptoUtil.GenerateDkimKeys(out privateKey, out publicKey); var domainCheckValue = PasswordGenerator.GenerateNewPassword(16); var domainCheck = Defines.ServerDnsDomainCheckPrefix + ": " + domainCheckValue; var serverDns = new ServerDns { Id = 0, Tenant = Tenant, User = User, DomainId = Defines.UNUSED_DNS_SETTING_DOMAIN_ID, DomainCheck = domainCheck, DkimSelector = Defines.ServerDnsDkimSelector, DkimPrivateKey = privateKey, DkimPublicKey = publicKey, DkimTtl = Defines.ServerDnsDefaultTtl, DkimVerified = false, DkimDateChecked = null, Spf = Defines.ServerDnsSpfRecordValue, SpfTtl = Defines.ServerDnsDefaultTtl, SpfVerified = false, SpfDateChecked = null, Mx = server.MxRecord, MxTtl = Defines.ServerDnsDefaultTtl, MxVerified = false, MxDateChecked = null, TimeModified = DateTime.UtcNow }; serverDns.Id = serverDnsDao.Save(serverDns); dnsSettings = serverDns; } var dnsData = new ServerDomainDnsData { Id = dnsSettings.Id, MxRecord = new ServerDomainMxRecordData { Host = dnsSettings.Mx, IsVerified = false, Priority = Defines.ServerDnsMxRecordPriority }, DkimRecord = new ServerDomainDkimRecordData { Selector = dnsSettings.DkimSelector, IsVerified = false, PublicKey = dnsSettings.DkimPublicKey }, DomainCheckRecord = new ServerDomainDnsRecordData { Name = Defines.DNS_DEFAULT_ORIGIN, IsVerified = false, Value = dnsSettings.DomainCheck }, SpfRecord = new ServerDomainDnsRecordData { Name = Defines.DNS_DEFAULT_ORIGIN, IsVerified = false, Value = dnsSettings.Spf } }; return(dnsData); }
public override KdfParameters GetBestParameters(uint uMilliseconds) { KdfParameters p = GetDefaultParameters(); ulong uRounds; // Try native method if (NativeLib.TransformKeyBenchmark256(uMilliseconds, out uRounds)) { p.SetUInt64(ParamRounds, uRounds); return(p); } if (TransformKeyBenchmarkGCrypt(uMilliseconds, out uRounds)) { p.SetUInt64(ParamRounds, uRounds); return(p); } byte[] pbKey = new byte[32]; byte[] pbNewKey = new byte[32]; for (int i = 0; i < pbKey.Length; ++i) { pbKey[i] = (byte)i; pbNewKey[i] = (byte)i; } #if KeePassUAP KeyParameter kp = new KeyParameter(pbKey); AesEngine aes = new AesEngine(); aes.Init(true, kp); #else byte[] pbIV = new byte[16]; using (SymmetricAlgorithm a = CryptoUtil.CreateAes()) { if (a.BlockSize != 128) // AES block size { Debug.Assert(false); a.BlockSize = 128; } a.KeySize = 256; a.Mode = CipherMode.ECB; using (ICryptoTransform t = a.CreateEncryptor(pbKey, pbIV)) { // !t.CanReuseTransform -- doesn't work with Mono if ((t == null) || (t.InputBlockSize != 16) || (t.OutputBlockSize != 16)) { Debug.Assert(false); p.SetUInt64(ParamRounds, PwDefs.DefaultKeyEncryptionRounds); return(p); } #endif uRounds = 0; int tStart = Environment.TickCount; while (true) { for (ulong j = 0; j < BenchStep; ++j) { #if KeePassUAP aes.ProcessBlock(pbNewKey, 0, pbNewKey, 0); aes.ProcessBlock(pbNewKey, 16, pbNewKey, 16); #else t.TransformBlock(pbNewKey, 0, 16, pbNewKey, 0); t.TransformBlock(pbNewKey, 16, 16, pbNewKey, 16); #endif } uRounds += BenchStep; if (uRounds < BenchStep) // Overflow check { uRounds = ulong.MaxValue; break; } uint tElapsed = (uint)(Environment.TickCount - tStart); if (tElapsed > uMilliseconds) { break; } } p.SetUInt64(ParamRounds, uRounds); #if KeePassUAP aes.Reset(); #else } } #endif return(p); }
private bool ReadHashedBlock() { if (m_bEos) { return(false); // End of stream reached already } m_nBufferPos = 0; if (m_brInput.ReadUInt32() != m_uBlockIndex) { throw new InvalidDataException(); } ++m_uBlockIndex; byte[] pbStoredHash = m_brInput.ReadBytes(32); if ((pbStoredHash == null) || (pbStoredHash.Length != 32)) { throw new InvalidDataException(); } int nBufferSize = 0; try { nBufferSize = m_brInput.ReadInt32(); } catch (NullReferenceException) // Mono bug workaround (LaunchPad 783268) { if (!NativeLib.IsUnix()) { throw; } } if (nBufferSize < 0) { throw new InvalidDataException(); } if (nBufferSize == 0) { for (int iHash = 0; iHash < 32; ++iHash) { if (pbStoredHash[iHash] != 0) { throw new InvalidDataException(); } } m_bEos = true; m_pbBuffer = MemUtil.EmptyByteArray; return(false); } m_pbBuffer = m_brInput.ReadBytes(nBufferSize); if ((m_pbBuffer == null) || ((m_pbBuffer.Length != nBufferSize) && m_bVerify)) { throw new InvalidDataException(); } if (m_bVerify) { byte[] pbComputedHash = CryptoUtil.HashSha256(m_pbBuffer); if ((pbComputedHash == null) || (pbComputedHash.Length != 32)) { throw new InvalidOperationException(); } if (!MemUtil.ArraysEqual(pbStoredHash, pbComputedHash)) { throw new InvalidDataException(); } } return(true); }
public HttpResponseMessage SpgatewayPayBill(PayView payView) { Pay pay_ = new Pay(); ModelState.Remove("Status"); ModelState.Remove("Message"); if (!ModelState.IsValid) { return(Request.CreateResponse(HttpStatusCode.OK, ModelState)); } pay_.OrderId = payView.OrderId; db.Pays.Add(pay_); db.SaveChanges(); Orders orders = db.Orders.Where(x => x.Id == payView.OrderId).FirstOrDefault(); string version = "1.5"; string payType = "CREDIT"; // 目前時間轉換 +08:00, 防止傳入時間或Server時間時區不同造成錯誤 DateTimeOffset taipeiStandardTimeOffset = DateTimeOffset.Now.ToOffset(new TimeSpan(8, 0, 0)); TradeInfo tradeInfo = new TradeInfo() { // * 商店代號 MerchantID = _bankInfoModel.MerchantID, // * 回傳格式 RespondType = "String", // * TimeStamp TimeStamp = taipeiStandardTimeOffset.ToUnixTimeSeconds().ToString(), // * 串接程式版本 Version = version, // * 商店訂單編號 MerchantOrderNo = pay_.Id.ToString(), // MerchantOrderNo = ordernumber, // * 訂單金額 Amt = (int)orders.Total, // * 商品資訊 ItemDesc = pay_.OrderId.ToString(), // 繳費有效期限(適用於非即時交易) ExpireDate = null, // 支付完成 返回商店網址 ReturnURL = _bankInfoModel.ReturnURL, // 支付通知網址 NotifyURL = _bankInfoModel.NotifyURL, // 商店取號網址 CustomerURL = _bankInfoModel.CustomerURL, // 支付取消 返回商店網址 ClientBackURL = null, // * 付款人電子信箱 Email = string.Empty, // 付款人電子信箱 是否開放修改(1=可修改 0=不可修改) EmailModify = 0, // 商店備註 OrderComment = "商店備註", // 信用卡 一次付清啟用(1=啟用、0或者未有此參數=不啟用) CREDIT = 1, // WEBATM啟用(1=啟用、0或者未有此參數,即代表不開啟) //WEBATM = null, // ATM 轉帳啟用(1=啟用、0或者未有此參數,即代表不開啟) //VACC = null, // 超商代碼繳費啟用(1=啟用、0或者未有此參數,即代表不開啟)(當該筆訂單金額小於 30 元或超過 2 萬元時,即使此參數設定為啟用,MPG 付款頁面仍不會顯示此支付方式選項。) //CVS = 1, // 超商條碼繳費啟用(1=啟用、0或者未有此參數,即代表不開啟)(當該筆訂單金額小於 20 元或超過 4 萬元時,即使此參數設定為啟用,MPG 付款頁面仍不會顯示此支付方式選項。) //BARCODE = 1 }; if (string.Equals(payType, "CREDIT")) { tradeInfo.CREDIT = 1; } else if (string.Equals(payType, "WEBATM")) { tradeInfo.WEBATM = 1; } else if (string.Equals(payType, "VACC")) { // 設定繳費截止日期 tradeInfo.ExpireDate = taipeiStandardTimeOffset.AddDays(1).ToString("yyyyMMdd"); tradeInfo.VACC = 1; } else if (string.Equals(payType, "CVS")) { // 設定繳費截止日期 tradeInfo.ExpireDate = taipeiStandardTimeOffset.AddDays(1).ToString("yyyyMMdd"); tradeInfo.CVS = 1; } else if (string.Equals(payType, "BARCODE")) { // 設定繳費截止日期 tradeInfo.ExpireDate = taipeiStandardTimeOffset.AddDays(1).ToString("yyyyMMdd"); tradeInfo.BARCODE = 1; } Atom <string> result = new Atom <string>() { IsSuccess = true }; var inputModel = new SpgatewayInputModel { MerchantID = _bankInfoModel.MerchantID, Version = version }; // 將model 轉換為List<KeyValuePair<string, string>>, null值不轉 List <KeyValuePair <string, string> > tradeData = LambdaUtil.ModelToKeyValuePairList <TradeInfo>(tradeInfo); // 將List<KeyValuePair<string, string>> 轉換為 key1=Value1&key2=Value2&key3=Value3... var tradeQueryPara = string.Join("&", tradeData.Select(x => $"{x.Key}={x.Value}")); // AES 加密 inputModel.TradeInfo = CryptoUtil.EncryptAESHex(tradeQueryPara, _bankInfoModel.HashKey, _bankInfoModel.HashIV); // SHA256 加密 inputModel.TradeSha = CryptoUtil.EncryptSHA256( $"HashKey={_bankInfoModel.HashKey}&{inputModel.TradeInfo}&HashIV={_bankInfoModel.HashIV}"); // 將model 轉換為List<KeyValuePair<string, string>>, null值不轉 List <KeyValuePair <string, string> > postData = LambdaUtil.ModelToKeyValuePairList <SpgatewayInputModel>(inputModel); //StringBuilder s = new StringBuilder(); //s.Append("<html>"); //s.AppendFormat("<body onload='document.forms[\"form\"].submit()'>"); //s.AppendFormat("<form name='form' action='{0}' method='post'>", _bankInfoModel.AuthUrl); //foreach (KeyValuePair<string, string> item in postData) //{ // s.AppendFormat("<input type='hidden' name='{0}' value='{1}' />", item.Key, item.Value); //} //s.Append("</form></body></html>"); return(Request.CreateResponse(HttpStatusCode.OK, postData)); }
/// <summary> /// Get Scheduled List for batch /// </summary> /// <param name="model"></param> /// <returns></returns> public ScheduleListViewModel GetBatchScheduledList(ScheduleListViewModel model) { var response = new ScheduleListViewModel(); try { IEnumerable <AdminScheduleViewModel> enumBatchScheduleList = (from scheduledBatch in _UnitOfWork.IAdminBatchScheduleRepository.RetrieveAll() join slots in _UnitOfWork.ISlotRepository.RetrieveAll() on scheduledBatch.SlotID equals slots.SlotID into ps from p in ps.DefaultIfEmpty() join repeats in _UnitOfWork.IRepeatRepository.RetrieveAll() on scheduledBatch.RepeatID equals repeats.RepeatID into rs from r in rs.DefaultIfEmpty() where scheduledBatch.IsDeleted != true && scheduledBatch.AdminID == model.LoggedInAdminId select new AdminScheduleViewModel { AdminSchID = scheduledBatch.AdminBatchSchID, AdminID = scheduledBatch.AdminID, CreatedOn = scheduledBatch.CreatedOn, RepeatID = scheduledBatch.RepeatID, RepeatInterval = r.RepeatInterval, ScheduleDate = scheduledBatch.ScheduleDate, SlotID = scheduledBatch.SlotID, SlotName = p.SlotName, BatchName = scheduledBatch.BatchName, Time = scheduledBatch.Time }).ToList(); foreach (var item in enumBatchScheduleList) { if (item.Time != null) { DateTime surveyDisplayTime = (DateTime)(item.Time); var Timestamp = surveyDisplayTime.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds; item.SlotTimeStamp = Timestamp.ToString(); } item.SlotTimeOptions = GetSlotTimeOptionsForBatch(item.AdminSchID); } List <AdminScheduleViewModel> gameList = new List <AdminScheduleViewModel>(); if (model.SearchId != null) { gameList = enumBatchScheduleList.ToList().FindAll(w => CryptoUtil.DecryptInfo(w.Name).StartsWith(model.SearchId)); } else { gameList = enumBatchScheduleList.ToList(); } string sortField = String.IsNullOrEmpty(model.SortPageOptions.SortField) ? "Name" : model.SortPageOptions.SortField; string sortDirection = String.IsNullOrEmpty(model.SortPageOptions.SortOrder) ? "asc" : model.SortPageOptions.SortOrder; switch (sortField) { case "BatchName": if (sortDirection == "asc") { gameList = gameList.OrderBy(c => CryptoUtil.DecryptInfo(c.Name)).ToList(); } else { gameList = gameList.OrderByDescending(c => CryptoUtil.DecryptInfo(c.Name)).ToList(); } break; case "CreatedOn": if (sortDirection == "asc") { gameList = gameList.OrderBy(c => c.CreatedOn).ToList(); } else { gameList = gameList.OrderByDescending(c => c.CreatedOn).ToList(); } break; default: gameList = gameList.OrderBy(c => CryptoUtil.DecryptInfo(c.Name)).ToList(); break; } response.AdminScheduleViewModelList = gameList; response.TotalRows = gameList.Count; } catch (Exception ex) { LogUtil.Error("BatchScheduleService/GetScheduledList: " + ex); response = new ScheduleListViewModel { Status = LAMPConstants.UNEXPECTED_ERROR, Message = ResourceHelper.GetStringResource(LAMPConstants.UNEXPECTED_ERROR) }; } return(response); }
private CacheableKeyRing CreateCacheableKeyRingCore(DateTimeOffset now, IKey keyJustAdded) { // Refresh the list of all keys var cacheExpirationToken = _keyManager.GetCacheExpirationToken(); var allKeys = _keyManager.GetAllKeys(); // Fetch the current default key from the list of all keys var defaultKeyPolicy = _defaultKeyResolver.ResolveDefaultKeyPolicy(now, allKeys); if (!defaultKeyPolicy.ShouldGenerateNewKey) { CryptoUtil.Assert(defaultKeyPolicy.DefaultKey != null, "Expected to see a default key."); return(CreateCacheableKeyRingCoreStep2(now, cacheExpirationToken, defaultKeyPolicy.DefaultKey, allKeys)); } _logger.PolicyResolutionStatesThatANewKeyShouldBeAddedToTheKeyRing(); // We shouldn't call CreateKey more than once, else we risk stack diving. This code path shouldn't // get hit unless there was an ineligible key with an activation date slightly later than the one we // just added. If this does happen, then we'll just use whatever key we can instead of creating // new keys endlessly, eventually falling back to the one we just added if all else fails. if (keyJustAdded != null) { var keyToUse = defaultKeyPolicy.DefaultKey ?? defaultKeyPolicy.FallbackKey ?? keyJustAdded; return(CreateCacheableKeyRingCoreStep2(now, cacheExpirationToken, keyToUse, allKeys)); } // At this point, we know we need to generate a new key. // We have been asked to generate a new key, but auto-generation of keys has been disabled. // We need to use the fallback key or fail. if (!_keyManagementOptions.AutoGenerateKeys) { var keyToUse = defaultKeyPolicy.DefaultKey ?? defaultKeyPolicy.FallbackKey; if (keyToUse == null) { _logger.KeyRingDoesNotContainValidDefaultKey(); throw new InvalidOperationException(Resources.KeyRingProvider_NoDefaultKey_AutoGenerateDisabled); } else { _logger.UsingFallbackKeyWithExpirationAsDefaultKey(keyToUse.KeyId, keyToUse.ExpirationDate); return(CreateCacheableKeyRingCoreStep2(now, cacheExpirationToken, keyToUse, allKeys)); } } if (defaultKeyPolicy.DefaultKey == null) { // The case where there's no default key is the easiest scenario, since it // means that we need to create a new key with immediate activation. var newKey = _keyManager.CreateNewKey(activationDate: now, expirationDate: now + _keyManagementOptions.NewKeyLifetime); return(CreateCacheableKeyRingCore(now, keyJustAdded: newKey)); // recursively call } else { // If there is a default key, then the new key we generate should become active upon // expiration of the default key. The new key lifetime is measured from the creation // date (now), not the activation date. var newKey = _keyManager.CreateNewKey(activationDate: defaultKeyPolicy.DefaultKey.ExpirationDate, expirationDate: now + _keyManagementOptions.NewKeyLifetime); return(CreateCacheableKeyRingCore(now, keyJustAdded: newKey)); // recursively call } }
public Installation?TryRegister(string path) { var executablePath = path; // Xtreme GoG and Steam var executable = InstallationUtils.GetFile(executablePath, "kkndgame.exe"); if (executable == null) { // Xtreme CD executablePath = InstallationUtils.GetDirectory(path, "game"); if (executablePath == null) { // Dos CD executablePath = InstallationUtils.GetDirectory(path, "kknd"); if (executablePath == null) { return(null); } } executable = InstallationUtils.GetFile(executablePath, "kknd.exe"); if (executable == null) { return(null); } } Log.Write("debug", $"Detected installation: {path}"); var release = CryptoUtil.SHA1Hash(File.OpenRead(executable)); var isXtreme = true; switch (release) { case "d1f41d7129b6f377869f28b89f92c18f4977a48f": Log.Write("debug", "=> Krush, Kill 'N' Destroy Xtreme (Steam/GoG, English)"); break; case "6fb10d85739ef63b28831ada4cdfc159a950c5d2": Log.Write("debug", "=> Krush, Kill 'N' Destroy Xtreme (Disc, English)"); break; case "024e96860c504b462b24b9237d49bfe8de6eb8e0": Log.Write("debug", "=> Krush, Kill 'N' Destroy (Disc, English)"); isXtreme = false; path = executablePath; break; default: Log.Write("debug", "=> Unsupported game version"); return(null); } var levelsFolder = InstallationUtils.GetDirectory(path, "levels"); if (levelsFolder == null) { Log.Write("debug", "=> Missing folder: levels"); return(null); } var fmvFolder = InstallationUtils.GetDirectory(path, "fmv"); if (fmvFolder == null) { Log.Write("debug", "=> Missing folder: fmv"); return(null); } var graphicsFolder = InstallationUtils.GetDirectory(levelsFolder, "640"); if (graphicsFolder == null) { Log.Write("debug", "=> Missing folder: 640"); return(null); } // Required files. var files = new Dictionary <string, string> { { "sprites.lvl", graphicsFolder }, { "surv.slv", levelsFolder }, { "mute.slv", levelsFolder }, { "mh_fmv.vbc", fmvFolder }, { "intro.vbc", fmvFolder } }.Concat( isXtreme ? new() { { "surv1.wav", levelsFolder }, { "surv2.wav", levelsFolder },
protected override byte[] DecryptImpl(byte *pbCiphertext, uint cbCiphertext, byte *pbAdditionalAuthenticatedData, uint cbAdditionalAuthenticatedData) { // Argument checking: input must at the absolute minimum contain a key modifier, nonce, and tag if (cbCiphertext < KEY_MODIFIER_SIZE_IN_BYTES + NONCE_SIZE_IN_BYTES + TAG_SIZE_IN_BYTES) { throw Error.CryptCommon_PayloadInvalid(); } // Assumption: pbCipherText := { keyModifier || nonce || encryptedData || authenticationTag } var cbPlaintext = checked (cbCiphertext - (KEY_MODIFIER_SIZE_IN_BYTES + NONCE_SIZE_IN_BYTES + TAG_SIZE_IN_BYTES)); var retVal = new byte[cbPlaintext]; fixed(byte *pbRetVal = retVal) { // Calculate offsets byte *pbKeyModifier = pbCiphertext; byte *pbNonce = &pbKeyModifier[KEY_MODIFIER_SIZE_IN_BYTES]; byte *pbEncryptedData = &pbNonce[NONCE_SIZE_IN_BYTES]; byte *pbAuthTag = &pbEncryptedData[cbPlaintext]; // Use the KDF to recreate the symmetric block cipher key // We'll need a temporary buffer to hold the symmetric encryption subkey byte *pbSymmetricDecryptionSubkey = stackalloc byte[checked ((int)_symmetricAlgorithmSubkeyLengthInBytes)]; try { _sp800_108_ctr_hmac_provider.DeriveKeyWithContextHeader( pbLabel: pbAdditionalAuthenticatedData, cbLabel: cbAdditionalAuthenticatedData, contextHeader: _contextHeader, pbContext: pbKeyModifier, cbContext: KEY_MODIFIER_SIZE_IN_BYTES, pbDerivedKey: pbSymmetricDecryptionSubkey, cbDerivedKey: _symmetricAlgorithmSubkeyLengthInBytes); // Perform the decryption operation using (var decryptionSubkeyHandle = _symmetricAlgorithmHandle.GenerateSymmetricKey(pbSymmetricDecryptionSubkey, _symmetricAlgorithmSubkeyLengthInBytes)) { byte dummy; byte *pbPlaintext = (pbRetVal != null) ? pbRetVal : &dummy; // CLR doesn't like pinning empty buffers BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO authInfo; BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO.Init(out authInfo); authInfo.pbNonce = pbNonce; authInfo.cbNonce = NONCE_SIZE_IN_BYTES; authInfo.pbTag = pbAuthTag; authInfo.cbTag = TAG_SIZE_IN_BYTES; // The call to BCryptDecrypt will also validate the authentication tag uint cbDecryptedBytesWritten; var ntstatus = UnsafeNativeMethods.BCryptDecrypt( hKey: decryptionSubkeyHandle, pbInput: pbEncryptedData, cbInput: cbPlaintext, pPaddingInfo: &authInfo, pbIV: null, // IV not used; nonce provided in pPaddingInfo cbIV: 0, pbOutput: pbPlaintext, cbOutput: cbPlaintext, pcbResult: out cbDecryptedBytesWritten, dwFlags: 0); UnsafeNativeMethods.ThrowExceptionForBCryptStatus(ntstatus); CryptoUtil.Assert(cbDecryptedBytesWritten == cbPlaintext, "cbDecryptedBytesWritten == cbPlaintext"); // At this point, retVal := { decryptedPayload } // And we're done! return(retVal); } } finally { // The buffer contains key material, so delete it. UnsafeBufferUtil.SecureZeroMemory(pbSymmetricDecryptionSubkey, _symmetricAlgorithmSubkeyLengthInBytes); } } }
public IHttpActionResult SpgatewayNotify() { // 取法同SpgatewayResult var httpRequestBase = new HttpRequestWrapper(HttpContext.Current.Request); RazorExtensions.LogFormData(httpRequestBase, "SpgatewayNotify(支付完成)"); // Status 回傳狀態 // MerchantID 回傳訊息 // TradeInfo 交易資料AES 加密 // TradeSha 交易資料SHA256 加密 // Version 串接程式版本 NameValueCollection collection = HttpContext.Current.Request.Form; if (collection["MerchantID"] != null && string.Equals(collection["MerchantID"], _bankInfoModel.MerchantID) && collection["TradeInfo"] != null && string.Equals(collection["TradeSha"], CryptoUtil.EncryptSHA256($"HashKey={_bankInfoModel.HashKey}&{collection["TradeInfo"]}&HashIV={_bankInfoModel.HashIV}"))) { var decryptTradeInfo = CryptoUtil.DecryptAESHex(collection["TradeInfo"], _bankInfoModel.HashKey, _bankInfoModel.HashIV); // 取得回傳參數(ex:key1=value1&key2=value2),儲存為NameValueCollection NameValueCollection decryptTradeCollection = HttpUtility.ParseQueryString(decryptTradeInfo); SpgatewayOutputDataModel convertModel = LambdaUtil.DictionaryToObject <SpgatewayOutputDataModel>(decryptTradeCollection.AllKeys.ToDictionary(k => k, k => decryptTradeCollection[k])); //LogUtil.WriteLog(JsonConvert.SerializeObject(convertModel)); // TODO 將回傳訊息寫入資料庫 VipOrder pay = db.VipOrders.Find(Convert.ToInt32(convertModel.MerchantOrderNo)); pay.Message = convertModel.Message; pay.Status = convertModel.Status; db.VipOrders.Add(pay); // return Content(JsonConvert.SerializeObject(convertModel)); if (pay.Status == "SUCCESS") { //MerchantOrderNo = "O202009100034" //convertModel.MerchantOrderNo VipOrder vip = db.VipOrders.Find(pay.BrandId); vip.Status = "已付款成功"; db.Entry(vip).State = EntityState.Modified; db.SaveChanges(); } else//付款失敗 { } return(Ok()); } else { //LogUtil.WriteLog("MerchantID/TradeSha驗證錯誤"); } return(Ok()); }
public IHttpActionResult SpgatewayPayBill(VipOrder vipOrder) { //var PayVip = db.VipOrders.Find(vipOrder.BrandId); //if (PayVip == null) //{ // return NotFound(); //} string token = Request.Headers.Authorization.Parameter; JwtAuthUtil jwtAuthUtil = new JwtAuthUtil(); int id = Convert.ToInt32(jwtAuthUtil.GetId(token)); // var payBrand = db.Brands.Where(b => b.Id == id); vipOrder.BrandId = id; db.VipOrders.Add(new VipOrder { BrandId = id, }); db.SaveChanges(); string version = "1.5"; // 目前時間轉換 +08:00, 防止傳入時間或Server時間時區不同造成錯誤 DateTimeOffset taipeiStandardTimeOffset = DateTimeOffset.Now.ToOffset(new TimeSpan(8, 0, 0)); TradeInfo tradeInfo = new TradeInfo() { // * 商店代號 MerchantID = _bankInfoModel.MerchantID, // * 回傳格式 RespondType = "String", // * TimeStamp TimeStamp = taipeiStandardTimeOffset.ToUnixTimeSeconds().ToString(), // * 串接程式版本 Version = version, // * 商店訂單編號 //MerchantOrderNo = $"T{DateTime.Now.ToString("yyyyMMddHHmm")}", MerchantOrderNo = vipOrder.BrandId.ToString(), // * 訂單金額 Amt = 1200, // * 商品資訊 ItemDesc = "數據分析功能" + vipOrder.BrandId.ToString(), // 繳費有效期限(適用於非即時交易) ExpireDate = null, // 支付完成 返回商店網址 ReturnURL = _bankInfoModel.ReturnURL, // 支付通知網址 NotifyURL = _bankInfoModel.NotifyURL, // 商店取號網址 CustomerURL = _bankInfoModel.CustomerURL, // 支付取消 返回商店網址 ClientBackURL = null, // * 付款人電子信箱 Email = string.Empty, // 付款人電子信箱 是否開放修改(1=可修改 0=不可修改) EmailModify = 0, // 商店備註 OrderComment = null, // 信用卡 一次付清啟用(1=啟用、0或者未有此參數=不啟用) CREDIT = null, // WEBATM啟用(1=啟用、0或者未有此參數,即代表不開啟) WEBATM = null, // ATM 轉帳啟用(1=啟用、0或者未有此參數,即代表不開啟) VACC = null, // 超商代碼繳費啟用(1=啟用、0或者未有此參數,即代表不開啟)(當該筆訂單金額小於 30 元或超過 2 萬元時,即使此參數設定為啟用,MPG 付款頁面仍不會顯示此支付方式選項。) CVS = null, // 超商條碼繳費啟用(1=啟用、0或者未有此參數,即代表不開啟)(當該筆訂單金額小於 20 元或超過 4 萬元時,即使此參數設定為啟用,MPG 付款頁面仍不會顯示此支付方式選項。) BARCODE = null }; //暫定都信用卡 tradeInfo.CREDIT = 1; //if (string.Equals(payType, "CREDIT")) //{ // tradeInfo.CREDIT = 1; //} //else if (string.Equals(payType, "WEBATM")) //{ // tradeInfo.WEBATM = 1; //} //else if (string.Equals(payType, "VACC")) //{ // // 設定繳費截止日期 // tradeInfo.ExpireDate = taipeiStandardTimeOffset.AddDays(1).ToString("yyyyMMdd"); // tradeInfo.VACC = 1; //} //else if (string.Equals(payType, "CVS")) //{ // // 設定繳費截止日期 // tradeInfo.ExpireDate = taipeiStandardTimeOffset.AddDays(1).ToString("yyyyMMdd"); // tradeInfo.CVS = 1; //} //else if (string.Equals(payType, "BARCODE")) //{ // // 設定繳費截止日期 // tradeInfo.ExpireDate = taipeiStandardTimeOffset.AddDays(1).ToString("yyyyMMdd"); // tradeInfo.BARCODE = 1; //} Atom <string> result = new Atom <string>() { IsSuccess = true }; var inputModel = new SpgatewayInputModel { MerchantID = _bankInfoModel.MerchantID, Version = version }; // 將model 轉換為List<KeyValuePair<string, string>>, null值不轉 List <KeyValuePair <string, string> > tradeData = LambdaUtil.ModelToKeyValuePairList <TradeInfo>(tradeInfo); // 將List<KeyValuePair<string, string>> 轉換為 key1=Value1&key2=Value2&key3=Value3... var tradeQueryPara = string.Join("&", tradeData.Select(x => $"{x.Key}={x.Value}")); // AES 加密 inputModel.TradeInfo = CryptoUtil.EncryptAESHex(tradeQueryPara, _bankInfoModel.HashKey, _bankInfoModel.HashIV); // SHA256 加密 inputModel.TradeSha = CryptoUtil.EncryptSHA256( $"HashKey={_bankInfoModel.HashKey}&{inputModel.TradeInfo}&HashIV={_bankInfoModel.HashIV}"); // 將model 轉換為List<KeyValuePair<string, string>>, null值不轉 List <KeyValuePair <string, string> > postData = LambdaUtil.ModelToKeyValuePairList <SpgatewayInputModel>(inputModel); return(Ok(postData)); }
/// <summary> /// Load a KDBX file from a stream. /// </summary> /// <param name="sSource">Stream to read the data from. Must contain /// a KDBX stream.</param> /// <param name="fmt">Format.</param> /// <param name="slLogger">Status logger (optional).</param> public void Load(Stream sSource, KdbxFormat fmt, IStatusLogger slLogger) { Debug.Assert(sSource != null); if (sSource == null) { throw new ArgumentNullException("sSource"); } if (m_bUsedOnce) { throw new InvalidOperationException("Do not reuse KdbxFile objects!"); } m_bUsedOnce = true; #if KDBX_BENCHMARK Stopwatch swTime = Stopwatch.StartNew(); #endif m_format = fmt; m_slLogger = slLogger; m_pbsBinaries.Clear(); UTF8Encoding encNoBom = StrUtil.Utf8; byte[] pbCipherKey = null; byte[] pbHmacKey64 = null; List <Stream> lStreams = new List <Stream>(); lStreams.Add(sSource); HashingStreamEx sHashing = new HashingStreamEx(sSource, false, null); lStreams.Add(sHashing); try { Stream sXml; if (fmt == KdbxFormat.Default) { BinaryReaderEx br = new BinaryReaderEx(sHashing, encNoBom, KLRes.FileCorrupted); byte[] pbHeader = LoadHeader(br); m_pbHashOfHeader = CryptoUtil.HashSha256(pbHeader); int cbEncKey, cbEncIV; ICipherEngine iCipher = GetCipher(out cbEncKey, out cbEncIV); ComputeKeys(out pbCipherKey, cbEncKey, out pbHmacKey64); string strIncomplete = KLRes.FileHeaderCorrupted + " " + KLRes.FileIncomplete; Stream sPlain; if (m_uFileVersion < FileVersion32_4) { Stream sDecrypted = EncryptStream(sHashing, iCipher, pbCipherKey, cbEncIV, false); if ((sDecrypted == null) || (sDecrypted == sHashing)) { throw new SecurityException(KLRes.CryptoStreamFailed); } lStreams.Add(sDecrypted); BinaryReaderEx brDecrypted = new BinaryReaderEx(sDecrypted, encNoBom, strIncomplete); byte[] pbStoredStartBytes = brDecrypted.ReadBytes(32); if ((m_pbStreamStartBytes == null) || (m_pbStreamStartBytes.Length != 32)) { throw new EndOfStreamException(strIncomplete); } if (!MemUtil.ArraysEqual(pbStoredStartBytes, m_pbStreamStartBytes)) { throw new InvalidCompositeKeyException(); } sPlain = new HashedBlockStream(sDecrypted, false, 0, !m_bRepairMode); } else // KDBX >= 4 { byte[] pbStoredHash = MemUtil.Read(sHashing, 32); if ((pbStoredHash == null) || (pbStoredHash.Length != 32)) { throw new EndOfStreamException(strIncomplete); } if (!MemUtil.ArraysEqual(m_pbHashOfHeader, pbStoredHash)) { throw new InvalidDataException(KLRes.FileHeaderCorrupted); } byte[] pbHeaderHmac = ComputeHeaderHmac(pbHeader, pbHmacKey64); byte[] pbStoredHmac = MemUtil.Read(sHashing, 32); if ((pbStoredHmac == null) || (pbStoredHmac.Length != 32)) { throw new EndOfStreamException(strIncomplete); } if (!MemUtil.ArraysEqual(pbHeaderHmac, pbStoredHmac)) { throw new InvalidCompositeKeyException(); } HmacBlockStream sBlocks = new HmacBlockStream(sHashing, false, !m_bRepairMode, pbHmacKey64); lStreams.Add(sBlocks); sPlain = EncryptStream(sBlocks, iCipher, pbCipherKey, cbEncIV, false); if ((sPlain == null) || (sPlain == sBlocks)) { throw new SecurityException(KLRes.CryptoStreamFailed); } } lStreams.Add(sPlain); if (m_pwDatabase.Compression == PwCompressionAlgorithm.GZip) { sXml = new GZipStream(sPlain, CompressionMode.Decompress); lStreams.Add(sXml); } else { sXml = sPlain; } if (m_uFileVersion >= FileVersion32_4) { LoadInnerHeader(sXml); // Binary header before XML } } else if (fmt == KdbxFormat.PlainXml) { sXml = sHashing; } else { Debug.Assert(false); throw new ArgumentOutOfRangeException("fmt"); } if (fmt == KdbxFormat.Default) { if (m_pbInnerRandomStreamKey == null) { Debug.Assert(false); throw new SecurityException("Invalid inner random stream key!"); } m_randomStream = new CryptoRandomStream(m_craInnerRandomStream, m_pbInnerRandomStreamKey); } #if KeePassDebug_WriteXml // FileStream fsOut = new FileStream("Raw.xml", FileMode.Create, // FileAccess.Write, FileShare.None); // try // { // while(true) // { // int b = sXml.ReadByte(); // if(b == -1) break; // fsOut.WriteByte((byte)b); // } // } // catch(Exception) { } // fsOut.Close(); #endif ReadXmlStreamed(sXml, sHashing); // ReadXmlDom(sXml); } catch (CryptographicException) // Thrown on invalid padding { throw new CryptographicException(KLRes.FileCorrupted); } finally { if (pbCipherKey != null) { MemUtil.ZeroByteArray(pbCipherKey); } if (pbHmacKey64 != null) { MemUtil.ZeroByteArray(pbHmacKey64); } CommonCleanUpRead(lStreams, sHashing); } #if KDBX_BENCHMARK swTime.Stop(); MessageService.ShowInfo("Loading KDBX took " + swTime.ElapsedMilliseconds.ToString() + " ms."); #endif }
/// <summary> /// Creates a new instance of a <see cref="DpapiXmlDecryptor"/>. /// </summary> /// <param name="services">An optional <see cref="IServiceProvider"/> to provide ancillary services.</param> public DpapiXmlDecryptor(IServiceProvider services) { CryptoUtil.AssertPlatformIsWindows(); _logger = services.GetLogger <DpapiXmlDecryptor>(); }
public void TestArchiveOperations() { //create file on disk var fileName = "c:\\temp\\testArchive2.rabbit"; // if (File.Exists(fileName)) { File.Delete(fileName); } var sizeInMb = 1; var binaryWriter = new BinaryWriter(new FileStream(fileName, FileMode.CreateNew)); CryptoUtil.WriteRandomBytes(binaryWriter, sizeInMb * 1048576, new byte[32]); binaryWriter.Flush(); binaryWriter.Close(); Assert.IsTrue(File.Exists(fileName)); //create archive with volumes var archive = new Archive(fileName, fileName, sizeInMb * 1048576); //MB x bytes archive.CreateVolumes(1, new string[] { "p1", "p2", "p3" }); Assert.IsTrue(archive.OpenVolume("p1")); Assert.IsTrue(archive.OpenVolume("p2")); Assert.IsTrue(archive.OpenVolume("p3")); //test add file var testFile = CreateFile("test1.txt", 100); archive.OpenVolume("p1"); archive.CurrentVolume.AddFile(testFile); archive.SaveCurrentVolume("p1"); //reopen volume and check added file archive.OpenVolume("p1"); Assert.IsTrue(archive.CurrentVolume.Folder.ContainsFile("test1.txt")); Assert.IsTrue(archive.CurrentVolume.Folder.Files[0].Data.SequenceEqual(testFile.Data)); //extract file archive.ExtractFile("test1.txt", "test1.txt"); Assert.IsTrue(File.Exists("test1.txt")); var buffer = File.ReadAllBytes("test1.txt"); Assert.IsTrue(archive.CurrentVolume.Folder.Files[0].Data.SequenceEqual(buffer)); File.Delete("test1.txt"); //remove file archive.CurrentVolume.Folder.DeleteFile("test1.txt"); archive.SaveCurrentVolume("p1"); archive.OpenVolume("p1"); //reopen Assert.IsTrue(archive.CurrentVolume.Folder.Files.Count == 0); var size = 100 * 1048576; var counter = 0; while (size > 1) { counter++; size -= 1068; size /= 2; } int i = 0; //1MB = 10 volumes, 10 MB = 14 volumes, }
///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // Decrypt and get the auth ticket /// <devdoc> /// <para>Given an encrypted authenitcation ticket as /// obtained from an HTTP cookie, this method returns an instance of a /// FormsAuthenticationTicket class.</para> /// </devdoc> public static FormsAuthenticationTicket Decrypt(string encryptedTicket) { if (String.IsNullOrEmpty(encryptedTicket) || encryptedTicket.Length > MAX_TICKET_LENGTH) { throw new ArgumentException(SR.GetString(SR.InvalidArgumentValue, "encryptedTicket")); } Initialize(); byte[] bBlob = null; if ((encryptedTicket.Length % 2) == 0) // Could be a hex string { try { bBlob = CryptoUtil.HexToBinary(encryptedTicket); } catch { } } if (bBlob == null) { bBlob = HttpServerUtility.UrlTokenDecode(encryptedTicket); } if (bBlob == null || bBlob.Length < 1) { throw new ArgumentException(SR.GetString(SR.InvalidArgumentValue, "encryptedTicket")); } int ticketLength; if (AspNetCryptoServiceProvider.Instance.IsDefaultProvider) { // If new crypto routines are enabled, call them instead. ICryptoService cryptoService = AspNetCryptoServiceProvider.Instance.GetCryptoService(Purpose.FormsAuthentication_Ticket); byte[] unprotectedData = cryptoService.Unprotect(bBlob); ticketLength = unprotectedData.Length; bBlob = unprotectedData; } else { #pragma warning disable 618 // calling obsolete methods // Otherwise call into MachineKeySection routines. if (_Protection == FormsProtectionEnum.All || _Protection == FormsProtectionEnum.Encryption) { // DevDiv Bugs 137864: Include a random IV if under the right compat mode // for improved encryption semantics bBlob = MachineKeySection.EncryptOrDecryptData(false, bBlob, null, 0, bBlob.Length, false, false, IVType.Random); if (bBlob == null) { return(null); } } ticketLength = bBlob.Length; if (_Protection == FormsProtectionEnum.All || _Protection == FormsProtectionEnum.Validation) { if (!MachineKeySection.VerifyHashedData(bBlob)) { return(null); } ticketLength -= MachineKeySection.HashSize; } #pragma warning restore 618 // calling obsolete methods } ////////////////////////////////////////////////////////////////////// // Step 4: Change binary ticket to managed struct // ** MSRC 11838 ** // Framework20 / Framework40 ticket generation modes are insecure. We should use a // secure serialization mode by default. if (!AppSettings.UseLegacyFormsAuthenticationTicketCompatibility) { return(FormsAuthenticationTicketSerializer.Deserialize(bBlob, ticketLength)); } // ** MSRC 11838 ** // If we have reached this point of execution, the developer has explicitly elected // to continue using the insecure code path instead of the secure one. We removed // the Framework40 serialization mode, so everybody using the legacy code path is // forced to Framework20. int iSize = ((ticketLength > MAX_TICKET_LENGTH) ? MAX_TICKET_LENGTH : ticketLength); StringBuilder name = new StringBuilder(iSize); StringBuilder data = new StringBuilder(iSize); StringBuilder path = new StringBuilder(iSize); byte [] pBin = new byte[4]; long [] pDates = new long[2]; int iRet = UnsafeNativeMethods.CookieAuthParseTicket(bBlob, ticketLength, name, iSize, data, iSize, path, iSize, pBin, pDates); if (iRet != 0) { return(null); } DateTime dt1 = DateTime.FromFileTime(pDates[0]); DateTime dt2 = DateTime.FromFileTime(pDates[1]); FormsAuthenticationTicket ticket = new FormsAuthenticationTicket((int)pBin[0], name.ToString(), dt1, dt2, (bool)(pBin[1] != 0), data.ToString(), path.ToString()); return(ticket); }
private byte[] CreateContextHeader() { var retVal = new byte[checked ( 1 /* KDF alg */ + 1 /* chaining mode */ + sizeof(uint) /* sym alg key size */ + sizeof(uint) /* GCM nonce size */ + sizeof(uint) /* sym alg block size */ + sizeof(uint) /* GCM tag size */ + TAG_SIZE_IN_BYTES /* tag of GCM-encrypted empty string */)]; fixed(byte *pbRetVal = retVal) { byte *ptr = pbRetVal; // First is the two-byte header *(ptr++) = 0; // 0x00 = SP800-108 CTR KDF w/ HMACSHA512 PRF *(ptr++) = 1; // 0x01 = GCM encryption + authentication // Next is information about the symmetric algorithm (key size, nonce size, block size, tag size) BitHelpers.WriteTo(ref ptr, _symmetricAlgorithmSubkeyLengthInBytes); BitHelpers.WriteTo(ref ptr, NONCE_SIZE_IN_BYTES); BitHelpers.WriteTo(ref ptr, TAG_SIZE_IN_BYTES); // block size = tag size BitHelpers.WriteTo(ref ptr, TAG_SIZE_IN_BYTES); // See the design document for an explanation of the following code. var tempKeys = new byte[_symmetricAlgorithmSubkeyLengthInBytes]; fixed(byte *pbTempKeys = tempKeys) { byte dummy; // Derive temporary key for encryption. using (var provider = SP800_108_CTR_HMACSHA512Util.CreateEmptyProvider()) { provider.DeriveKey( pbLabel: &dummy, cbLabel: 0, pbContext: &dummy, cbContext: 0, pbDerivedKey: pbTempKeys, cbDerivedKey: (uint)tempKeys.Length); } // Encrypt a zero-length input string with an all-zero nonce and copy the tag to the return buffer. byte *pbNonce = stackalloc byte[(int)NONCE_SIZE_IN_BYTES]; UnsafeBufferUtil.SecureZeroMemory(pbNonce, NONCE_SIZE_IN_BYTES); DoGcmEncrypt( pbKey: pbTempKeys, cbKey: _symmetricAlgorithmSubkeyLengthInBytes, pbNonce: pbNonce, pbPlaintextData: &dummy, cbPlaintextData: 0, pbEncryptedData: &dummy, pbTag: ptr); } ptr += TAG_SIZE_IN_BYTES; CryptoUtil.Assert(ptr - pbRetVal == retVal.Length, "ptr - pbRetVal == retVal.Length"); } // retVal := { version || chainingMode || symAlgKeySize || nonceSize || symAlgBlockSize || symAlgTagSize || TAG-of-E("") }. return(retVal); }
internal static String Encrypt(FormsAuthenticationTicket ticket, bool hexEncodedTicket) { if (ticket == null) { throw new ArgumentNullException("ticket"); } Initialize(); ////////////////////////////////////////////////////////////////////// // Step 1a: Make it into a binary blob byte[] bBlob = MakeTicketIntoBinaryBlob(ticket); if (bBlob == null) { return(null); } ////////////////////////////////////////////////////////////////////// // Step 1b: If new crypto routines are enabled, call them instead. if (AspNetCryptoServiceProvider.Instance.IsDefaultProvider) { ICryptoService cryptoService = AspNetCryptoServiceProvider.Instance.GetCryptoService(Purpose.FormsAuthentication_Ticket); byte[] protectedData = cryptoService.Protect(bBlob); bBlob = protectedData; } else { #pragma warning disable 618 // calling obsolete methods // otherwise.. ////////////////////////////////////////////////////////////////////// // Step 2: Get the MAC and add to the blob if (_Protection == FormsProtectionEnum.All || _Protection == FormsProtectionEnum.Validation) { byte[] bMac = MachineKeySection.HashData(bBlob, null, 0, bBlob.Length); if (bMac == null) { return(null); } byte[] bAll = new byte[bMac.Length + bBlob.Length]; Buffer.BlockCopy(bBlob, 0, bAll, 0, bBlob.Length); Buffer.BlockCopy(bMac, 0, bAll, bBlob.Length, bMac.Length); bBlob = bAll; } if (_Protection == FormsProtectionEnum.All || _Protection == FormsProtectionEnum.Encryption) { ////////////////////////////////////////////////////////////////////// // Step 3: Do the actual encryption // DevDiv Bugs 137864: Include a random IV if under the right compat mode // for improved encryption semantics bBlob = MachineKeySection.EncryptOrDecryptData(true, bBlob, null, 0, bBlob.Length, false, false, IVType.Random); } #pragma warning restore 618 // calling obsolete methods } if (!hexEncodedTicket) { return(HttpServerUtility.UrlTokenEncode(bBlob)); } else { return(CryptoUtil.BinaryToHex(bBlob)); } }
private static byte[] HashData(byte[] pb) { return(MemUtil.Mid(CryptoUtil.HashSha256(pb), 0, KfxDataHashLength)); }
IKey IInternalXmlKeyManager.CreateNewKey(Guid keyId, DateTimeOffset creationDate, DateTimeOffset activationDate, DateTimeOffset expirationDate) { // <key id="{guid}" version="1"> // <creationDate>...</creationDate> // <activationDate>...</activationDate> // <expirationDate>...</expirationDate> // <descriptor deserializerType="{typeName}"> // ... // </descriptor> // </key> _logger.CreatingKey(keyId, creationDate, activationDate, expirationDate); var newDescriptor = _authenticatedEncryptorConfiguration.CreateNewDescriptor() ?? CryptoUtil.Fail <IAuthenticatedEncryptorDescriptor>("CreateNewDescriptor returned null."); var descriptorXmlInfo = newDescriptor.ExportToXml(); _logger.DescriptorDeserializerTypeForKeyIs(keyId, descriptorXmlInfo.DeserializerType.AssemblyQualifiedName !); // build the <key> element var keyElement = new XElement(KeyElementName, new XAttribute(IdAttributeName, keyId), new XAttribute(VersionAttributeName, 1), new XElement(CreationDateElementName, creationDate), new XElement(ActivationDateElementName, activationDate), new XElement(ExpirationDateElementName, expirationDate), new XElement(DescriptorElementName, new XAttribute(DeserializerTypeAttributeName, descriptorXmlInfo.DeserializerType.AssemblyQualifiedName !), descriptorXmlInfo.SerializedDescriptorElement)); // If key escrow policy is in effect, write the *unencrypted* key now. if (_keyEscrowSink != null) { _logger.KeyEscrowSinkFoundWritingKeyToEscrow(keyId); } else { _logger.NoKeyEscrowSinkFoundNotWritingKeyToEscrow(keyId); } _keyEscrowSink?.Store(keyId, keyElement); // If an XML encryptor has been configured, protect secret key material now. if (KeyEncryptor == null) { _logger.NoXMLEncryptorConfiguredKeyMayBePersistedToStorageInUnencryptedForm(keyId); } var possiblyEncryptedKeyElement = KeyEncryptor?.EncryptIfNecessary(keyElement) ?? keyElement; // Persist it to the underlying repository and trigger the cancellation token. var friendlyName = string.Format(CultureInfo.InvariantCulture, "key-{0:D}", keyId); KeyRepository.StoreElement(possiblyEncryptedKeyElement, friendlyName); TriggerAndResetCacheExpirationToken(); // And we're done! return(new Key( keyId: keyId, creationDate: creationDate, activationDate: activationDate, expirationDate: expirationDate, descriptor: newDescriptor, encryptorFactories: _encryptorFactories)); }
public byte[] Decrypt(ArraySegment <byte> protectedPayload, ArraySegment <byte> additionalAuthenticatedData) { protectedPayload.Validate(); additionalAuthenticatedData.Validate(); // Argument checking - input must at the absolute minimum contain a key modifier, IV, and MAC if (protectedPayload.Count < checked (KEY_MODIFIER_SIZE_IN_BYTES + _symmetricAlgorithmBlockSizeInBytes + _validationAlgorithmDigestLengthInBytes)) { throw Error.CryptCommon_PayloadInvalid(); } // Assumption: protectedPayload := { keyModifier | IV | encryptedData | MAC(IV | encryptedPayload) } try { // Step 1: Extract the key modifier and IV from the payload. int keyModifierOffset; // position in protectedPayload.Array where key modifier begins int ivOffset; // position in protectedPayload.Array where key modifier ends / IV begins int ciphertextOffset; // position in protectedPayload.Array where IV ends / ciphertext begins int macOffset; // position in protectedPayload.Array where ciphertext ends / MAC begins int eofOffset; // position in protectedPayload.Array where MAC ends checked { keyModifierOffset = protectedPayload.Offset; ivOffset = keyModifierOffset + KEY_MODIFIER_SIZE_IN_BYTES; ciphertextOffset = ivOffset + _symmetricAlgorithmBlockSizeInBytes; } ArraySegment <byte> keyModifier = new ArraySegment <byte>(protectedPayload.Array !, keyModifierOffset, ivOffset - keyModifierOffset); var iv = new byte[_symmetricAlgorithmBlockSizeInBytes]; Buffer.BlockCopy(protectedPayload.Array !, ivOffset, iv, 0, iv.Length); // Step 2: Decrypt the KDK and use it to restore the original encryption and MAC keys. // We pin all unencrypted keys to limit their exposure via GC relocation. var decryptedKdk = new byte[_keyDerivationKey.Length]; var decryptionSubkey = new byte[_symmetricAlgorithmSubkeyLengthInBytes]; var validationSubkey = new byte[_validationAlgorithmSubkeyLengthInBytes]; var derivedKeysBuffer = new byte[checked (decryptionSubkey.Length + validationSubkey.Length)]; fixed(byte *__unused__1 = decryptedKdk) fixed(byte *__unused__2 = decryptionSubkey) fixed(byte *__unused__3 = validationSubkey) fixed(byte *__unused__4 = derivedKeysBuffer) { try { _keyDerivationKey.WriteSecretIntoBuffer(new ArraySegment <byte>(decryptedKdk)); ManagedSP800_108_CTR_HMACSHA512.DeriveKeysWithContextHeader( kdk: decryptedKdk, label: additionalAuthenticatedData, contextHeader: _contextHeader, context: keyModifier, prfFactory: _kdkPrfFactory, output: new ArraySegment <byte>(derivedKeysBuffer)); Buffer.BlockCopy(derivedKeysBuffer, 0, decryptionSubkey, 0, decryptionSubkey.Length); Buffer.BlockCopy(derivedKeysBuffer, decryptionSubkey.Length, validationSubkey, 0, validationSubkey.Length); // Step 3: Calculate the correct MAC for this payload. // correctHash := MAC(IV || ciphertext) byte[] correctHash; using (var hashAlgorithm = CreateValidationAlgorithm(validationSubkey)) { checked { eofOffset = protectedPayload.Offset + protectedPayload.Count; macOffset = eofOffset - _validationAlgorithmDigestLengthInBytes; } correctHash = hashAlgorithm.ComputeHash(protectedPayload.Array !, ivOffset, macOffset - ivOffset); } // Step 4: Validate the MAC provided as part of the payload. if (!CryptoUtil.TimeConstantBuffersAreEqual(correctHash, 0, correctHash.Length, protectedPayload.Array !, macOffset, eofOffset - macOffset)) { throw Error.CryptCommon_PayloadInvalid(); // integrity check failure } // Step 5: Decipher the ciphertext and return it to the caller. using (var symmetricAlgorithm = CreateSymmetricAlgorithm()) using (var cryptoTransform = symmetricAlgorithm.CreateDecryptor(decryptionSubkey, iv)) { var outputStream = new MemoryStream(); using (var cryptoStream = new CryptoStream(outputStream, cryptoTransform, CryptoStreamMode.Write)) { cryptoStream.Write(protectedPayload.Array !, ciphertextOffset, macOffset - ciphertextOffset); cryptoStream.FlushFinalBlock(); // At this point, outputStream := { plaintext }, and we're done! return(outputStream.ToArray()); } } } finally { // delete since these contain secret material Array.Clear(decryptedKdk, 0, decryptedKdk.Length); Array.Clear(decryptionSubkey, 0, decryptionSubkey.Length); Array.Clear(validationSubkey, 0, validationSubkey.Length); Array.Clear(derivedKeysBuffer, 0, derivedKeysBuffer.Length); } } } catch (Exception ex) when(ex.RequiresHomogenization()) { // Homogenize all exceptions to CryptographicException. throw Error.CryptCommon_GenericError(ex); } }
public static void Main(string[] args) { string validationKeyAsText = null, decryptionKeyAsText = null, textToDecrypt = null, purposeKey = null, fileToDecrypt = null; bool showhelp = false, isBase64 = false; var p = new OptionSet { { "vk=", "the validation key (in hex)", v => validationKeyAsText = v }, { "dk=", "the decryption key (in hex)", v => decryptionKeyAsText = v }, { "p|purpose=", "the encryption context\n(currently only: owin.cookie)", v => purposeKey = v }, { "base64", "data is provided in base64 format (otherwise we assume hex)", v => isBase64 = v != null }, { "i|input=", "input data file (when too big for command line)", v => fileToDecrypt = v }, { "h|help", "Show this message and exit", v => showhelp = v != null }, { "?", "Show this message and exit", v => showhelp = v != null } }; try { textToDecrypt = p.Parse(args).FirstOrDefault(); if (textToDecrypt == null && fileToDecrypt != null) { if (!File.Exists(fileToDecrypt)) { throw new OptionException("input file does not exist", "input"); } textToDecrypt = File.ReadAllText(fileToDecrypt); } } catch (OptionException ex) { Console.Error.Write("ERROR: invalid argument, "); Console.Error.WriteLine(ex.Message); Console.Error.WriteLine(); showhelp = true; } if (!showhelp && textToDecrypt == null) { Console.Error.WriteLine("ERROR: please provide data to decrypt"); Console.Error.WriteLine(); showhelp = true; } if (!showhelp && (validationKeyAsText == null || decryptionKeyAsText == null || purposeKey == null)) { Console.Error.WriteLine("ERROR: all parameters are required"); Console.Error.WriteLine(); showhelp = true; } Purpose purpose = null; if (!showhelp && !purposeMap.TryGetValue(purposeKey, out purpose)) { Console.Error.WriteLine("ERROR: invalid purpose"); Console.Error.WriteLine(); showhelp = true; } if (showhelp) { ShowHelp(p); return; } Debug.Assert(purpose != null); Debug.Assert(textToDecrypt != null); Debug.Assert(decryptionKeyAsText != null); Debug.Assert(validationKeyAsText != null); byte[] encryptedData; if (isBase64) { try { encryptedData = HttpEncoder.Default.UrlTokenDecode(textToDecrypt); } catch (FormatException) { encryptedData = null; } } else { if (textToDecrypt.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) { textToDecrypt = textToDecrypt.Substring(2); } encryptedData = CryptoUtil.HexToBinary(textToDecrypt); } byte[] decryptionKey = CryptoUtil.HexToBinary(decryptionKeyAsText.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? decryptionKeyAsText.Substring(2) : decryptionKeyAsText); byte[] validationKey = CryptoUtil.HexToBinary(validationKeyAsText.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? validationKeyAsText.Substring(2) : validationKeyAsText); if (decryptionKey == null || validationKey == null) { Console.Error.WriteLine("ERROR: invalid encryption or validation key"); Console.Error.WriteLine(); return; } if (encryptedData == null) { Console.Error.WriteLine("ERROR: invalid data to decrypt - must be either base64 or hex"); Console.Error.WriteLine(); return; } Console.WriteLine(); var decryptor = new AspNetDecryptor(purpose, new CryptographicKey(decryptionKey), new CryptographicKey(validationKey), "owin.cookie".Equals(purposeKey, StringComparison.Ordinal)); var decryptedData = decryptor.DecryptData(encryptedData); Console.WriteLine(Hexify.Hex.PrettyPrint(decryptedData)); Console.WriteLine(); }
private byte[] CreateContextHeader() { var EMPTY_ARRAY = Array.Empty <byte>(); var EMPTY_ARRAY_SEGMENT = new ArraySegment <byte>(EMPTY_ARRAY); var retVal = new byte[checked ( 1 /* KDF alg */ + 1 /* chaining mode */ + sizeof(uint) /* sym alg key size */ + sizeof(uint) /* sym alg block size */ + sizeof(uint) /* hmac alg key size */ + sizeof(uint) /* hmac alg digest size */ + _symmetricAlgorithmBlockSizeInBytes /* ciphertext of encrypted empty string */ + _validationAlgorithmDigestLengthInBytes /* digest of HMACed empty string */)]; var idx = 0; // First is the two-byte header retVal[idx++] = 0; // 0x00 = SP800-108 CTR KDF w/ HMACSHA512 PRF retVal[idx++] = 0; // 0x00 = CBC encryption + HMAC authentication // Next is information about the symmetric algorithm (key size followed by block size) BitHelpers.WriteTo(retVal, ref idx, _symmetricAlgorithmSubkeyLengthInBytes); BitHelpers.WriteTo(retVal, ref idx, _symmetricAlgorithmBlockSizeInBytes); // Next is information about the keyed hash algorithm (key size followed by digest size) BitHelpers.WriteTo(retVal, ref idx, _validationAlgorithmSubkeyLengthInBytes); BitHelpers.WriteTo(retVal, ref idx, _validationAlgorithmDigestLengthInBytes); // See the design document for an explanation of the following code. var tempKeys = new byte[_symmetricAlgorithmSubkeyLengthInBytes + _validationAlgorithmSubkeyLengthInBytes]; ManagedSP800_108_CTR_HMACSHA512.DeriveKeys( kdk: EMPTY_ARRAY, label: EMPTY_ARRAY_SEGMENT, context: EMPTY_ARRAY_SEGMENT, prfFactory: _kdkPrfFactory, output: new ArraySegment <byte>(tempKeys)); // At this point, tempKeys := { K_E || K_H }. // Encrypt a zero-length input string with an all-zero IV and copy the ciphertext to the return buffer. using (var symmetricAlg = CreateSymmetricAlgorithm()) { using (var cryptoTransform = symmetricAlg.CreateEncryptor( rgbKey: new ArraySegment <byte>(tempKeys, 0, _symmetricAlgorithmSubkeyLengthInBytes).AsStandaloneArray(), rgbIV: new byte[_symmetricAlgorithmBlockSizeInBytes])) { var ciphertext = cryptoTransform.TransformFinalBlock(EMPTY_ARRAY, 0, 0); CryptoUtil.Assert(ciphertext != null && ciphertext.Length == _symmetricAlgorithmBlockSizeInBytes, "ciphertext != null && ciphertext.Length == _symmetricAlgorithmBlockSizeInBytes"); Buffer.BlockCopy(ciphertext, 0, retVal, idx, ciphertext.Length); } } idx += _symmetricAlgorithmBlockSizeInBytes; // MAC a zero-length input string and copy the digest to the return buffer. using (var hashAlg = CreateValidationAlgorithm(new ArraySegment <byte>(tempKeys, _symmetricAlgorithmSubkeyLengthInBytes, _validationAlgorithmSubkeyLengthInBytes).AsStandaloneArray())) { var digest = hashAlg.ComputeHash(EMPTY_ARRAY); CryptoUtil.Assert(digest != null && digest.Length == _validationAlgorithmDigestLengthInBytes, "digest != null && digest.Length == _validationAlgorithmDigestLengthInBytes"); Buffer.BlockCopy(digest, 0, retVal, idx, digest.Length); } idx += _validationAlgorithmDigestLengthInBytes; CryptoUtil.Assert(idx == retVal.Length, "idx == retVal.Length"); // retVal := { version || chainingMode || symAlgKeySize || symAlgBlockSize || macAlgKeySize || macAlgDigestSize || E("") || MAC("") }. return(retVal); }
public HttpResponseMessage SpgatewayNotify() { // Status 回傳狀態 // MerchantID 回傳訊息 // TradeInfo 交易資料AES 加密 // TradeSha 交易資料SHA256 加密 // Version 串接程式版本 var collection = HttpContext.Current.Request; if (collection["MerchantID"] != null && string.Equals(collection["MerchantID"], _bankInfoModel.MerchantID) && collection["TradeInfo"] != null && string.Equals(collection["TradeSha"], CryptoUtil.EncryptSHA256($"HashKey={_bankInfoModel.HashKey}&{collection["TradeInfo"]}&HashIV={_bankInfoModel.HashIV}"))) { var decryptTradeInfo = CryptoUtil.DecryptAESHex(collection["TradeInfo"], _bankInfoModel.HashKey, _bankInfoModel.HashIV); // 取得回傳參數(ex:key1=value1&key2=value2),儲存為NameValueCollection NameValueCollection decryptTradeCollection = HttpUtility.ParseQueryString(decryptTradeInfo); SpgatewayOutputDataModel convertModel = LambdaUtil.DictionaryToObject <SpgatewayOutputDataModel>( decryptTradeCollection.AllKeys.ToDictionary(k => k, k => decryptTradeCollection[k])); Pay pay = db.Pays.Find(Convert.ToInt32(convertModel.MerchantOrderNo)); pay.Message = convertModel.Message; pay.Status = convertModel.Status; db.Pays.Add(pay); if (pay.Status == "SUCCESS") { Orders orders = db.Orders.Find(pay.OrderId); orders.Status = OrderType.已付款; db.Entry(orders).State = EntityState.Modified; db.SaveChanges(); } // TODO 將回傳訊息寫入資料庫 } return(Request.CreateResponse(HttpStatusCode.OK)); }
/// <summary> /// This action filter is called before an action execution. /// </summary> /// <param name="filterContext"></param> /// <returns></returns> protected override void OnActionExecuting(ActionExecutingContext filterContext) { IEnumerable <Claim> claims = ClaimsPrincipal.Current.Claims; if (claims != null) { if (claims.Count() > 0) { var adminId = claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid); if (adminId != null) { loggedInUserId = Convert.ToInt64(adminId.Value); } } } //To Get Logged in User Name var email = claims.FirstOrDefault(c => c.Type == ClaimTypes.Email); if (email != null) { var newEmail = CryptoUtil.EncryptInfo(email.Value);//email.Value if (_UnitOfWork.IAdminRepository.RetrieveAll().Where(u => u.Email == newEmail && u.IsDeleted != true).FirstOrDefault() != null) { loggedInFirstName = ((from admin in _UnitOfWork.IAdminRepository.RetrieveAll().Where(u => u.Email == newEmail && u.IsDeleted != true) select admin.FirstName).FirstOrDefault()); loggedInLastName = ((from admin in _UnitOfWork.IAdminRepository.RetrieveAll().Where(u => u.Email == newEmail && u.IsDeleted != true) select admin.LastName).FirstOrDefault()); ViewBag.Name = CryptoUtil.DecryptInfo(loggedInFirstName) + " " + CryptoUtil.DecryptInfo(loggedInLastName); } else { ViewBag.Name = ""; } } }
private static uint GetKeySizeInBits(int value) { CryptoUtil.Assert(value >= 0, "value >= 0"); CryptoUtil.Assert(value % 8 == 0, "value % 8 == 0"); return((uint)value); }
// PRF function as defined in Rfc2898 PBKDF2 spec /// <summary> /// The prf. /// </summary> /// <param name="S"> /// The s. /// </param> /// <param name="hmacKey"> /// The hmac key. /// </param> /// <returns> /// The byte. /// </returns> private byte[] PRF(byte[] S, byte[] hmacKey) { // HMACSHA512 Hashing, better than the HMACSHA1 in Microsofts implementation ;) return(CryptoUtil.ComputeHmac512(hmacKey, S)); }
// public void Save(string strFile, PwGroup pgDataSource, KdbxFormat fmt, // IStatusLogger slLogger) // { // bool bMadeUnhidden = UrlUtil.UnhideFile(strFile); // // IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFile); // this.Save(IOConnection.OpenWrite(ioc), pgDataSource, format, slLogger); // // if(bMadeUnhidden) UrlUtil.HideFile(strFile, true); // Hide again // } /// <summary> /// Save the contents of the current <c>PwDatabase</c> to a KDBX file. /// </summary> /// <param name="sSaveTo">Stream to write the KDBX file into.</param> /// <param name="pgDataSource">Group containing all groups and /// entries to write. If <c>null</c>, the complete database will /// be written.</param> /// <param name="fmt">Format of the file to create.</param> /// <param name="slLogger">Logger that recieves status information.</param> public void Save(Stream sSaveTo, PwGroup pgDataSource, KdbxFormat fmt, IStatusLogger slLogger) { Debug.Assert(sSaveTo != null); if (sSaveTo == null) { throw new ArgumentNullException("sSaveTo"); } if (m_bUsedOnce) { throw new InvalidOperationException("Do not reuse KdbxFile objects!"); } m_bUsedOnce = true; m_format = fmt; m_slLogger = slLogger; PwGroup pgRoot = (pgDataSource ?? m_pwDatabase.RootGroup); UTF8Encoding encNoBom = StrUtil.Utf8; CryptoRandom cr = CryptoRandom.Instance; byte[] pbCipherKey = null; byte[] pbHmacKey64 = null; m_pbsBinaries.Clear(); m_pbsBinaries.AddFrom(pgRoot); List <Stream> lStreams = new List <Stream>(); lStreams.Add(sSaveTo); HashingStreamEx sHashing = new HashingStreamEx(sSaveTo, true, null); lStreams.Add(sHashing); try { m_uFileVersion = GetMinKdbxVersion(); int cbEncKey, cbEncIV; ICipherEngine iCipher = GetCipher(out cbEncKey, out cbEncIV); m_pbMasterSeed = cr.GetRandomBytes(32); m_pbEncryptionIV = cr.GetRandomBytes((uint)cbEncIV); // m_pbTransformSeed = cr.GetRandomBytes(32); PwUuid puKdf = m_pwDatabase.KdfParameters.KdfUuid; KdfEngine kdf = KdfPool.Get(puKdf); if (kdf == null) { throw new Exception(KLRes.UnknownKdf + MessageService.NewParagraph + // KLRes.FileNewVerOrPlgReq + MessageService.NewParagraph + "UUID: " + puKdf.ToHexString() + "."); } kdf.Randomize(m_pwDatabase.KdfParameters); if (m_format == KdbxFormat.Default) { if (m_uFileVersion < FileVersion32_4) { m_craInnerRandomStream = CrsAlgorithm.Salsa20; m_pbInnerRandomStreamKey = cr.GetRandomBytes(32); } else // KDBX >= 4 { m_craInnerRandomStream = CrsAlgorithm.ChaCha20; m_pbInnerRandomStreamKey = cr.GetRandomBytes(64); } m_randomStream = new CryptoRandomStream(m_craInnerRandomStream, m_pbInnerRandomStreamKey); } if (m_uFileVersion < FileVersion32_4) { m_pbStreamStartBytes = cr.GetRandomBytes(32); } Stream sXml; if (m_format == KdbxFormat.Default) { byte[] pbHeader = GenerateHeader(); m_pbHashOfHeader = CryptoUtil.HashSha256(pbHeader); MemUtil.Write(sHashing, pbHeader); sHashing.Flush(); ComputeKeys(out pbCipherKey, cbEncKey, out pbHmacKey64); Stream sPlain; if (m_uFileVersion < FileVersion32_4) { Stream sEncrypted = EncryptStream(sHashing, iCipher, pbCipherKey, cbEncIV, true); if ((sEncrypted == null) || (sEncrypted == sHashing)) { throw new SecurityException(KLRes.CryptoStreamFailed); } lStreams.Add(sEncrypted); MemUtil.Write(sEncrypted, m_pbStreamStartBytes); sPlain = new HashedBlockStream(sEncrypted, true); } else // KDBX >= 4 { // For integrity checking (without knowing the master key) MemUtil.Write(sHashing, m_pbHashOfHeader); byte[] pbHeaderHmac = ComputeHeaderHmac(pbHeader, pbHmacKey64); MemUtil.Write(sHashing, pbHeaderHmac); Stream sBlocks = new HmacBlockStream(sHashing, true, true, pbHmacKey64); lStreams.Add(sBlocks); sPlain = EncryptStream(sBlocks, iCipher, pbCipherKey, cbEncIV, true); if ((sPlain == null) || (sPlain == sBlocks)) { throw new SecurityException(KLRes.CryptoStreamFailed); } } lStreams.Add(sPlain); if (m_pwDatabase.Compression == PwCompressionAlgorithm.GZip) { sXml = new GZipStream(sPlain, CompressionMode.Compress); lStreams.Add(sXml); } else { sXml = sPlain; } if (m_uFileVersion >= FileVersion32_4) { WriteInnerHeader(sXml); // Binary header before XML } } else if (m_format == KdbxFormat.PlainXml) { sXml = sHashing; } else { Debug.Assert(false); throw new ArgumentOutOfRangeException("fmt"); } #if KeePassUAP XmlWriterSettings xws = new XmlWriterSettings(); xws.Encoding = encNoBom; xws.Indent = true; xws.IndentChars = "\t"; xws.NewLineOnAttributes = false; XmlWriter xw = XmlWriter.Create(sXml, xws); #else XmlTextWriter xw = new XmlTextWriter(sXml, encNoBom); xw.Formatting = Formatting.Indented; xw.IndentChar = '\t'; xw.Indentation = 1; #endif m_xmlWriter = xw; WriteDocument(pgRoot); m_xmlWriter.Flush(); m_xmlWriter.Close(); } finally { if (pbCipherKey != null) { MemUtil.ZeroByteArray(pbCipherKey); } if (pbHmacKey64 != null) { MemUtil.ZeroByteArray(pbHmacKey64); } CommonCleanUpWrite(lStreams, sHashing); } }
private byte[] UnprotectCore(byte[] protectedData, bool allowOperationsOnRevokedKeys, out UnprotectStatus status) { Debug.Assert(protectedData != null); try { // argument & state checking if (protectedData.Length < sizeof(uint) /* magic header */ + sizeof(Guid) /* key id */) { // payload must contain at least the magic header and key id throw Error.ProtectionProvider_BadMagicHeader(); } // Need to check that protectedData := { magicHeader || keyId || encryptorSpecificProtectedPayload } // Parse the payload version number and key id. uint magicHeaderFromPayload; Guid keyIdFromPayload; fixed(byte *pbInput = protectedData) { magicHeaderFromPayload = ReadBigEndian32BitInteger(pbInput); keyIdFromPayload = Read32bitAlignedGuid(&pbInput[sizeof(uint)]); } // Are the magic header and version information correct? int payloadVersion; if (!TryGetVersionFromMagicHeader(magicHeaderFromPayload, out payloadVersion)) { throw Error.ProtectionProvider_BadMagicHeader(); } else if (payloadVersion != 0) { throw Error.ProtectionProvider_BadVersion(); } if (_logger.IsDebugLevelEnabled()) { _logger.PerformingUnprotectOperationToKeyWithPurposes(keyIdFromPayload, JoinPurposesForLog(Purposes)); } // Find the correct encryptor in the keyring. bool keyWasRevoked; var currentKeyRing = _keyRingProvider.GetCurrentKeyRing(); var requestedEncryptor = currentKeyRing.GetAuthenticatedEncryptorByKeyId(keyIdFromPayload, out keyWasRevoked); if (requestedEncryptor == null) { if (_keyRingProvider is KeyRingProvider provider && provider.InAutoRefreshWindow()) { currentKeyRing = provider.RefreshCurrentKeyRing(); requestedEncryptor = currentKeyRing.GetAuthenticatedEncryptorByKeyId(keyIdFromPayload, out keyWasRevoked); } if (requestedEncryptor == null) { _logger.KeyWasNotFoundInTheKeyRingUnprotectOperationCannotProceed(keyIdFromPayload); throw Error.Common_KeyNotFound(keyIdFromPayload); } } // Do we need to notify the caller that he should reprotect the data? status = UnprotectStatus.Ok; if (keyIdFromPayload != currentKeyRing.DefaultKeyId) { status = UnprotectStatus.DefaultEncryptionKeyChanged; } // Do we need to notify the caller that this key was revoked? if (keyWasRevoked) { if (allowOperationsOnRevokedKeys) { _logger.KeyWasRevokedCallerRequestedUnprotectOperationProceedRegardless(keyIdFromPayload); status = UnprotectStatus.DecryptionKeyWasRevoked; } else { _logger.KeyWasRevokedUnprotectOperationCannotProceed(keyIdFromPayload); throw Error.Common_KeyRevoked(keyIdFromPayload); } } // Perform the decryption operation. ArraySegment <byte> ciphertext = new ArraySegment <byte>(protectedData, sizeof(uint) + sizeof(Guid), protectedData.Length - (sizeof(uint) + sizeof(Guid))); // chop off magic header + encryptor id ArraySegment <byte> additionalAuthenticatedData = new ArraySegment <byte>(_aadTemplate.GetAadForKey(keyIdFromPayload, isProtecting: false)); // At this point, cipherText := { encryptorSpecificPayload }, // so all that's left is to invoke the decryption routine directly. return(requestedEncryptor.Decrypt(ciphertext, additionalAuthenticatedData) ?? CryptoUtil.Fail <byte[]>("IAuthenticatedEncryptor.Decrypt returned null.")); } catch (Exception ex) when(ex.RequiresHomogenization()) { // homogenize all failures to CryptographicException throw Error.DecryptionFailed(ex); } }
private CachedKeyRing CreateCachedKeyRingInstanceUnderLock(DateTime utcNow, CachedKeyRing existingCachedKeyRing) { bool shouldCreateNewKeyWithDeferredActivation; // flag stating whether the default key will soon expire and doesn't have a suitable replacement // Must we discard the cached keyring and refresh directly from the manager? if (existingCachedKeyRing != null && existingCachedKeyRing.HardRefreshTimeUtc <= utcNow) { existingCachedKeyRing = null; } // Try to locate the current default key, using the cached keyring if we can. IKey defaultKey; if (existingCachedKeyRing != null) { defaultKey = FindDefaultKey(utcNow, existingCachedKeyRing.Keys, out shouldCreateNewKeyWithDeferredActivation); if (defaultKey != null && !shouldCreateNewKeyWithDeferredActivation) { return(new CachedKeyRing { KeyRing = new KeyRing(defaultKey.KeyId, existingCachedKeyRing.KeyRing), // this overload allows us to use existing IAuthenticatedEncryptor instances Keys = existingCachedKeyRing.Keys, HardRefreshTimeUtc = existingCachedKeyRing.HardRefreshTimeUtc, SoftRefreshTimeUtc = MinDateTime(existingCachedKeyRing.HardRefreshTimeUtc, utcNow + KEYRING_REFRESH_PERIOD) }); } } // That didn't work, so refresh from the underlying key manager. var allKeys = _keyManager.GetAllKeys().ToArray(); defaultKey = FindDefaultKey(utcNow, allKeys, out shouldCreateNewKeyWithDeferredActivation); if (defaultKey != null && shouldCreateNewKeyWithDeferredActivation) { // If we need to create a new key with deferred activation, do so now. _keyManager.CreateNewKey(activationDate: defaultKey.ExpirationDate, expirationDate: utcNow + KEY_DEFAULT_LIFETIME); allKeys = _keyManager.GetAllKeys().ToArray(); defaultKey = FindDefaultKey(utcNow, allKeys); } else if (defaultKey == null) { // If there's no default key, create one now with immediate activation. _keyManager.CreateNewKey(utcNow, utcNow + KEY_DEFAULT_LIFETIME); allKeys = _keyManager.GetAllKeys().ToArray(); defaultKey = FindDefaultKey(utcNow, allKeys); } // We really should have a default key at this point. CryptoUtil.Assert(defaultKey != null, "defaultKey != null"); var cachedKeyRingHardRefreshTime = GetNextHardRefreshTime(utcNow); return(new CachedKeyRing { KeyRing = new KeyRing(defaultKey.KeyId, allKeys), Keys = allKeys, HardRefreshTimeUtc = cachedKeyRingHardRefreshTime, SoftRefreshTimeUtc = MinDateTime(defaultKey.ExpirationDate.UtcDateTime, cachedKeyRingHardRefreshTime) }); }
void ValidateClient(Connection newConn, string data) { try { if (State == ServerState.GameStarted) { Log.Write("server", "Rejected connection from {0}; game is already started.", newConn.Socket.RemoteEndPoint); SendOrderTo(newConn, "ServerError", "The game has already started"); DropClient(newConn); return; } var handshake = HandshakeResponse.Deserialize(data); if (!string.IsNullOrEmpty(Settings.Password) && handshake.Password != Settings.Password) { var message = string.IsNullOrEmpty(handshake.Password) ? "Server requires a password" : "Incorrect password"; SendOrderTo(newConn, "AuthenticationError", message); DropClient(newConn); return; } var ipAddress = ((IPEndPoint)newConn.Socket.RemoteEndPoint).Address; var client = new Session.Client { Name = OpenRA.Settings.SanitizedPlayerName(handshake.Client.Name), IPAddress = ipAddress.ToString(), AnonymizedIPAddress = Type != ServerType.Local && Settings.ShareAnonymizedIPs ? Session.AnonymizeIP(ipAddress) : null, Location = GeoIP.LookupCountry(ipAddress), Index = newConn.PlayerIndex, PreferredColor = handshake.Client.PreferredColor, Color = handshake.Client.Color, Faction = "Random", SpawnPoint = 0, Team = 0, State = Session.ClientState.Invalid, }; if (ModData.Manifest.Id != handshake.Mod) { Log.Write("server", "Rejected connection from {0}; mods do not match.", newConn.Socket.RemoteEndPoint); SendOrderTo(newConn, "ServerError", "Server is running an incompatible mod"); DropClient(newConn); return; } if (ModData.Manifest.Metadata.Version != handshake.Version) { Log.Write("server", "Rejected connection from {0}; Not running the same version.", newConn.Socket.RemoteEndPoint); SendOrderTo(newConn, "ServerError", "Server is running an incompatible version"); DropClient(newConn); return; } if (handshake.OrdersProtocol != ProtocolVersion.Orders) { Log.Write("server", "Rejected connection from {0}; incompatible Orders protocol version {1}.", newConn.Socket.RemoteEndPoint, handshake.OrdersProtocol); SendOrderTo(newConn, "ServerError", "Server is running an incompatible protocol"); DropClient(newConn); return; } // Check if IP is banned var bans = Settings.Ban.Union(TempBans); if (bans.Contains(client.IPAddress)) { Log.Write("server", "Rejected connection from {0}; Banned.", newConn.Socket.RemoteEndPoint); SendOrderTo(newConn, "ServerError", "You have been {0} from the server".F(Settings.Ban.Contains(client.IPAddress) ? "banned" : "temporarily banned")); DropClient(newConn); return; } Action completeConnection = () => { client.Slot = LobbyInfo.FirstEmptySlot(); client.IsAdmin = !LobbyInfo.Clients.Any(c1 => c1.IsAdmin); if (client.IsObserver && !LobbyInfo.GlobalSettings.AllowSpectators) { SendOrderTo(newConn, "ServerError", "The game is full"); DropClient(newConn); return; } if (client.Slot != null) { SyncClientToPlayerReference(client, Map.Players.Players[client.Slot]); } else { client.Color = Color.White; } // Promote connection to a valid client PreConns.Remove(newConn); Conns.Add(newConn); LobbyInfo.Clients.Add(client); newConn.Validated = true; var clientPing = new Session.ClientPing { Index = client.Index }; LobbyInfo.ClientPings.Add(clientPing); Log.Write("server", "Client {0}: Accepted connection from {1}.", newConn.PlayerIndex, newConn.Socket.RemoteEndPoint); if (client.Fingerprint != null) { Log.Write("server", "Client {0}: Player fingerprint is {1}.", newConn.PlayerIndex, client.Fingerprint); } foreach (var t in serverTraits.WithInterface <IClientJoined>()) { t.ClientJoined(this, newConn); } SyncLobbyInfo(); Log.Write("server", "{0} ({1}) has joined the game.", client.Name, newConn.Socket.RemoteEndPoint); // Report to all other players SendMessage("{0} has joined the game.".F(client.Name), newConn); // Send initial ping SendOrderTo(newConn, "Ping", Game.RunTime.ToString(CultureInfo.InvariantCulture)); if (Type == ServerType.Dedicated) { var motdFile = Platform.ResolvePath(Platform.SupportDirPrefix, "motd.txt"); if (!File.Exists(motdFile)) { File.WriteAllText(motdFile, "Welcome, have fun and good luck!"); } var motd = File.ReadAllText(motdFile); if (!string.IsNullOrEmpty(motd)) { SendOrderTo(newConn, "Message", motd); } } if (Map.DefinesUnsafeCustomRules) { SendOrderTo(newConn, "Message", "This map contains custom rules. Game experience may change."); } if (!LobbyInfo.GlobalSettings.EnableSingleplayer) { SendOrderTo(newConn, "Message", TwoHumansRequiredText); } else if (Map.Players.Players.Where(p => p.Value.Playable).All(p => !p.Value.AllowBots)) { SendOrderTo(newConn, "Message", "Bots have been disabled on this map."); } }; if (Type == ServerType.Local) { // Local servers can only be joined by the local client, so we can trust their identity without validation client.Fingerprint = handshake.Fingerprint; completeConnection(); } else if (!string.IsNullOrEmpty(handshake.Fingerprint) && !string.IsNullOrEmpty(handshake.AuthSignature)) { waitingForAuthenticationCallback++; Action <DownloadDataCompletedEventArgs> onQueryComplete = i => { PlayerProfile profile = null; if (i.Error == null) { try { var yaml = MiniYaml.FromString(Encoding.UTF8.GetString(i.Result)).First(); if (yaml.Key == "Player") { profile = FieldLoader.Load <PlayerProfile>(yaml.Value); var publicKey = Encoding.ASCII.GetString(Convert.FromBase64String(profile.PublicKey)); var parameters = CryptoUtil.DecodePEMPublicKey(publicKey); if (!profile.KeyRevoked && CryptoUtil.VerifySignature(parameters, newConn.AuthToken, handshake.AuthSignature)) { client.Fingerprint = handshake.Fingerprint; Log.Write("server", "{0} authenticated as {1} (UID {2})", newConn.Socket.RemoteEndPoint, profile.ProfileName, profile.ProfileID); } else if (profile.KeyRevoked) { profile = null; Log.Write("server", "{0} failed to authenticate as {1} (key revoked)", newConn.Socket.RemoteEndPoint, handshake.Fingerprint); } else { profile = null; Log.Write("server", "{0} failed to authenticate as {1} (signature verification failed)", newConn.Socket.RemoteEndPoint, handshake.Fingerprint); } } else { Log.Write("server", "{0} failed to authenticate as {1} (invalid server response: `{2}` is not `Player`)", newConn.Socket.RemoteEndPoint, handshake.Fingerprint, yaml.Key); } } catch (Exception ex) { Log.Write("server", "{0} failed to authenticate as {1} (exception occurred)", newConn.Socket.RemoteEndPoint, handshake.Fingerprint); Log.Write("server", ex.ToString()); } } else { Log.Write("server", "{0} failed to authenticate as {1} (server error: `{2}`)", newConn.Socket.RemoteEndPoint, handshake.Fingerprint, i.Error); } delayedActions.Add(() => { var notAuthenticated = Type == ServerType.Dedicated && profile == null && (Settings.RequireAuthentication || Settings.ProfileIDWhitelist.Any()); var blacklisted = Type == ServerType.Dedicated && profile != null && Settings.ProfileIDBlacklist.Contains(profile.ProfileID); var notWhitelisted = Type == ServerType.Dedicated && Settings.ProfileIDWhitelist.Any() && (profile == null || !Settings.ProfileIDWhitelist.Contains(profile.ProfileID)); if (notAuthenticated) { Log.Write("server", "Rejected connection from {0}; Not authenticated.", newConn.Socket.RemoteEndPoint); SendOrderTo(newConn, "ServerError", "Server requires players to have an OpenRA forum account"); DropClient(newConn); } else if (blacklisted || notWhitelisted) { if (blacklisted) { Log.Write("server", "Rejected connection from {0}; In server blacklist.", newConn.Socket.RemoteEndPoint); } else { Log.Write("server", "Rejected connection from {0}; Not in server whitelist.", newConn.Socket.RemoteEndPoint); } SendOrderTo(newConn, "ServerError", "You do not have permission to join this server"); DropClient(newConn); } else { completeConnection(); } waitingForAuthenticationCallback--; }, 0); }; new Download(playerDatabase.Profile + handshake.Fingerprint, _ => { }, onQueryComplete); } else { if (Type == ServerType.Dedicated && (Settings.RequireAuthentication || Settings.ProfileIDWhitelist.Any())) { Log.Write("server", "Rejected connection from {0}; Not authenticated.", newConn.Socket.RemoteEndPoint); SendOrderTo(newConn, "ServerError", "Server requires players to have an OpenRA forum account"); DropClient(newConn); } else { completeConnection(); } } } catch (Exception ex) { Log.Write("server", "Dropping connection {0} because an error occurred:", newConn.Socket.RemoteEndPoint); Log.Write("server", ex.ToString()); DropClient(newConn); } }