成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何使用DNS構建無成本的區(qū)塊鏈數(shù)據(jù)庫

運維 數(shù)據(jù)庫運維
區(qū)塊鏈不僅是一個流行詞。它也不限于加密貨幣和比特幣。憑借其創(chuàng)造透明度和公平性的能力,這項技術正在革新各個領域。應用范圍從跟蹤系統(tǒng)到保護數(shù)據(jù),再到執(zhí)行在線投票系統(tǒng)。

[[387427]]

本文轉載自微信公眾號「區(qū)塊鏈研究實驗室」,作者鏈三豐。轉載本文請聯(lián)系區(qū)塊鏈研究實驗室公眾號。   

區(qū)塊鏈不僅是一個流行詞。它也不限于加密貨幣和比特幣。憑借其創(chuàng)造透明度和公平性的能力,這項技術正在革新各個領域。應用范圍從跟蹤系統(tǒng)到保護數(shù)據(jù),再到執(zhí)行在線投票系統(tǒng)。它可以幫助實施反洗錢跟蹤系統(tǒng),或者簡單地跟蹤您在商店購買的產(chǎn)品的來源。

就像信息科學中經(jīng)常發(fā)生的那樣,許多區(qū)塊鏈平臺管理著所有的復雜性,使我們可以像保存一個簡單的數(shù)據(jù)庫一樣簡單地保存數(shù)據(jù)。

在本文中,我想實現(xiàn)一個區(qū)塊鏈數(shù)據(jù)庫,以了解此類解決方案的關鍵要素。而且,為了使其更具挑戰(zhàn)性,我將在不使用任何數(shù)據(jù)庫或服務器的情況下做到這一點。

該解決方案可以輕松地使您擁有可以驗證并安全存儲的不可變數(shù)據(jù)。

這篇文章的結構如下:

  • 什么是區(qū)塊鏈數(shù)據(jù)庫及其使用方式
  • 如何僅使用DNS服務來實現(xiàn)區(qū)塊鏈

什么是區(qū)塊鏈數(shù)據(jù)庫以及如何使用

像往常一樣,我們可以從Wikipedia定義開始:

“A blockchain,[ ...],是一個越來越多的記錄,稱為塊,正在使用鏈接加密。每個塊都包含前一個塊的加密哈希,即時間戳[..]。通過設計,區(qū)塊鏈可以抵抗其數(shù)據(jù)的修改。這是因為一旦記錄,任何給定塊中的數(shù)據(jù)都不能追溯更改,而無需更改所有后續(xù)塊。

“對于用作分布式總賬,一個blockchain通常由管理對等網(wǎng)絡的網(wǎng)絡共同地粘附到協(xié)議用于節(jié)點間通信和驗證新塊”。

換句話說,區(qū)塊鏈的主要特征是:

  • 通過將一條記錄連接到上一條記錄來存儲數(shù)據(jù)
  • 做到這一點,因此您不能在不使所有數(shù)據(jù)順序不一致的情況下更改一條記錄
  • 將數(shù)據(jù)存儲在分布式數(shù)據(jù)庫中

那么,如何創(chuàng)建呢?

我想的是,一個節(jié)點的鏈或多或少是一個鏈表,其中每個塊都有一個不可變的哈希。完成此操作后,您只需要一個安全的分布式數(shù)據(jù)庫即可存儲數(shù)據(jù)。什么是古老的分布式數(shù)據(jù)庫?好吧,每個人都有一個分布式數(shù)據(jù)庫,沒人知道!我說的是DNS。是的,它是分布式的,它存儲數(shù)據(jù)。每個人都有一個DNS服務。我意識到這不是預期的用途,但讓我們一起玩吧。

該協(xié)議的工作流程是受信任的機構將數(shù)據(jù)寫入DNS。每個記錄都有一個唯一的鍵,該鍵是內(nèi)容的哈希值。這意味著,通過更改數(shù)據(jù),您將更改ID,并且指向該ID的所有子代都將不一致。此外,DNS協(xié)議是分布式的,因此許多服務器之間共享數(shù)據(jù)的許多副本,這意味著您的一個DNS將脫機,而另一個將繼續(xù)為數(shù)據(jù)提供服務。還請考慮DNS被廣泛緩存,這使您的通信性能高(使用不可變數(shù)據(jù)緩存永遠不會成為問題)。

該系統(tǒng)使用所有公司都已經(jīng)擁有的DNS作為存儲,因此無需任何額外費用。DNS本身是一個分布式數(shù)據(jù)庫。

現(xiàn)在我們已經(jīng)定義了存儲數(shù)據(jù)的位置,我們只需要了解如何存儲數(shù)據(jù)即可。下一步是定義一個通信協(xié)議,使所有各方都可以扮演自己的角色。下圖顯示了流程。

DNS區(qū)塊鏈工作流程。

在上圖中,我們有:

  • 在DNS上發(fā)布的推力實體。它是寫作的關鍵-其他人可以寫記錄,但是它們是無法理解的。
  • 一個消費者,即推力生產(chǎn)者和讀取數(shù)據(jù)
  • 數(shù)據(jù),其 可以是任何JSON數(shù)據(jù)。您可以選擇將其公開或不公開。

如何實施

現(xiàn)在我們知道該怎么做,并且已經(jīng)有了啟動該工具的工具,我們只需要使用源代碼即可。

為了使用DNS實現(xiàn)區(qū)塊鏈,我們必須面對一些重要問題:

  • DNS限制-DNS并非旨在存儲大數(shù)據(jù)。我們想使用TXT記錄,但是它們只有254個字符。如果我們要存儲一個大的JSON對象,這是一個很大的限制。
  • 安全性-即使我們想保持數(shù)據(jù)公開,DNS使用的UDP協(xié)議也存在問題。它沒有經(jīng)過加密,并且沒有像HTTPS協(xié)議中那樣可以推動授權的證書機制。
  • 數(shù)據(jù)是按設計公開的—這可能是一個問題。

所有這些方面都有一個解決方案,并且您將看到,它很容易實現(xiàn)。實際上,通過使用加密技術和獨創(chuàng)性,我們將為上述所有問題找到一個明智的解決方案。

讓我們看看它是如何工作的。

創(chuàng)建沙盒環(huán)境

第一步是創(chuàng)建一個我們想玩的沙盒環(huán)境。我們需要啟動該工作的是帶有API系統(tǒng)的本地DNS服務器。我們通過創(chuàng)建一個托管該文件的docker-compose文件來實現(xiàn)這一目標。我使用了一個Visual Studio項目,在其中創(chuàng)建了一個我們將用于驗證數(shù)據(jù)的Web應用程序,一個將成為我們核心的庫以及一個測試項目。結果如下:

DNS區(qū)塊鏈項目

通過運行docker-compose up,所有啟動并準備好進行測試。對于DNS部分,我使用了非常輕巧且具有HTTP API可用的DNS。它使用以下配置運行:

  1. version: '3.4' 
  2. services: 
  3.   blockchaindns.web: 
  4.     image: ${DOCKER_REGISTRY-}blockchaindnsweb 
  5.     build: 
  6.       context: . 
  7.       dockerfile: BlockChainDNS.Web/Dockerfile 
  8.   dns: 
  9.     image: tgpfeiffer/shaman-dns   
  10.     command: shaman --server --token xxx --api-listen 0.0.0.0:1632 --dns-listen 0.0.0.0:53 -l trace --insecure   
  11.     ports: 
  12.       - 1632:1632 
  13.       - 53:53/udp 

這里xxx是您要用于身份驗證的令牌,并且DNS已配置為接受來自所有主機的請求(0.0.0.0:port)。

使用運行它之后docker-compose up,您可以使用控制臺對其進行測試:

  1. #create a record in Shaman DNS 
  2. curl --location --request POST 'localhost:1632/records' \ 
  3. --header 'Content-Type: application/json' \ 
  4. --data-raw '{ 
  5.   "domain""test.myfakedomain.it."
  6.   "records": [ 
  7.     { 
  8.       "ttl": 60, 
  9.       "class""IN"
  10.       "type""A"
  11.       "address""127.0.0.1" 
  12.     } 
  13.   ] 
  14. }' 
  15. #test the record 
  16. nslookup test.myfakedomain.it 127.0.0.1 
  17. #output 
  18. # Server:  UnKnown 
  19. # Address:  127.0.0.1 
  20. # Response from server: 
  21. # Nome:    test.myfakedomain.it 
  22. # Address:  127.0.0.1 

現(xiàn)在我們有了一個可以正常工作的本地DNS,我們可以創(chuàng)建一個可以通過API管理DNS記錄的客戶端。

DNS客戶端

第二步是包裝要在應用程序中使用的DNS客戶端功能。我想在這里做的是將來有能力更改DNS服務,因此我創(chuàng)建了一個接口和一個類實現(xiàn)。以下代碼片段顯示了該界面:

  1. public interface IDNSClient 
  2.   Task<DNSEntry> GetRecord(string host, string zone); 
  3.   Task<bool> AddRecord(DNSEntry entry); 
  4.   Action Init { get; set; } 

如您所見,客戶端實現(xiàn)執(zhí)行HTTP調(diào)用來存儲記錄。您可以在本文末尾的GitHub項目中找到完整的類實現(xiàn)。我們僅為薩滿實施了本地提供商,但很容易對其進行擴展以支持大多數(shù)現(xiàn)代托管提供商上的任何商業(yè)DNS。

區(qū)塊鏈服務

現(xiàn)在我們已經(jīng)有了執(zhí)行部分,是時候?qū)崿F(xiàn)業(yè)務邏輯了。所有工作都在客戶端完成,客戶端將計算要存儲的數(shù)據(jù)并調(diào)用DNS客戶端方法以保留記錄。服務層由兩部分組成:

  • BlockChainNode:節(jié)點的表示形式
  • BlockChainService:實現(xiàn)邏輯的服務

讓我們詳細了解這些類如何工作。

區(qū)塊鏈節(jié)點

這是帶有JObject屬性的簡單類,用戶可以在其中存儲任何數(shù)據(jù)。它計算密鑰哈希數(shù)據(jù)。數(shù)據(jù)包含歷史記錄,該歷史記錄是到父項的鏈接。僅更改數(shù)據(jù)的字節(jié)將更改密鑰,這將導致以下節(jié)點不一致。以下代碼顯示了該類最重要的部分。

  1. public class BlockChainNode 
  2.     { 
  3.  
  4.         public BlockChainNode() 
  5.         { 
  6.  
  7.             this.History.CollectionChanged += History_CollectionChanged; 
  8.         } 
  9.  
  10.         private void History_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
  11.         { 
  12.             this.Data["_history"] = JArray.FromObject(this.History); 
  13.         } 
  14.  
  15.  
  16.         private JObject _data = new JObject(); 
  17.         public JObject Data 
  18.         { 
  19.             get { return _data; } 
  20.             set { _data = value; History_CollectionChanged(nullnull); } 
  21.         } 
  22.  
  23.  
  24.  
  25.         public string Hash { get 
  26.             { 
  27.                 return GetHash(this.ToBase64()); 
  28.             } 
  29.         }  
  30.  
  31.  
  32.  
  33.         public ObservableCollection<string> History { get; set; } = new ObservableCollection<string>();//First to last 
  34.  
  35.         public string ToBase64() 
  36.         { 
  37.             var content = UnicodeEncoding.Unicode.GetBytes(Data.ToString(Formatting.None)); 
  38.  
  39.             return Convert.ToBase64String(content); 
  40.         } 
  41.  
  42.  
  43.         public static string GetHash(string text) 
  44.         { 
  45.             using (var md5 = MD5.Create()) 
  46.             { 
  47.                 return Base32.ToBase32String(md5.ComputeHash(UTF8Encoding.UTF8.GetBytes(text))).ToLower();                 
  48.             } 
  49.         } 
  50.     } 

該代碼最相關的部分是:

  • 數(shù)據(jù)對象:用戶可以在其中存儲數(shù)據(jù)的JSON對象
  • 歷史記錄:與數(shù)據(jù)同步的可觀察列表(“歷史記錄”中的任何更改都會更改_history節(jié)點,反之亦然。)
  • 哈希:根據(jù)數(shù)據(jù)的文本表示形式的MD5計算得出的哈希。結果以Base32算法編碼-類似于Base 64,但僅使用四個字節(jié)且僅包含小寫字符。這是因為DNS不區(qū)分大小寫,并且使用廣泛使用的Base64編碼產(chǎn)生了不一致的數(shù)據(jù)。

現(xiàn)在我們有了模型,我們必須繼續(xù)下一步:由服務實現(xiàn)的業(yè)務邏輯。

區(qū)塊鏈服務

區(qū)塊鏈服務實現(xiàn)用于保存,讀取和驗證記錄的方法。困難的部分是要解決DNS服務器記錄長度的255個字符的限制。解決方案是在Base64中對內(nèi)容進行編碼,然后使用命名約定將其拆分成塊保存在不同的記錄中。密鑰用作URL的一部分。因此,對于該項目mykey.domain.dom,我們將有0.mykey.domain.dom,1.mykey.domain.dom等下一段代碼顯示了節(jié)能方法。

  1. private int WriteDNSFragmentedText(string baseUrl, string value, int size
  2.     var tokens = Tokenize(value, size).ToList(); 
  3.     int i = 0; 
  4.     foreach (var token in tokens) 
  5.     { 
  6.         WriteDNSRecord($"{i}.{baseUrl}""TXT", token); 
  7.         i++; 
  8.     } 
  9.     return i ; 
  10.  
  11. private void WriteDNSRecord(string domain, string type, string value) 
  12.     this.client.AddRecord(new DNSEntry() 
  13.     { 
  14.         Domain = domain, 
  15.         Type = type, 
  16.         Value = value 
  17.     }); 

從上一個調(diào)用的片段中可以看到WriteDNSFragmentedText,輸入文本被拆分,數(shù)據(jù)被保存在許多DNS條目中。

讀取數(shù)據(jù)是相反的。我嘗試獲取子記錄0,1,2,依此類推,直到有數(shù)據(jù)為止。一旦我收集了所有Base64塊,過程就是將它們連接,解碼并獲取純JSON。

  1. private string ReadDNSFragmentedText(string domain) 
  2.     List<string> fragments = new List<string>(); 
  3.  
  4.     for (int i = 0; i < 1000; i++)  
  5.     { 
  6.         var fragmentUrl = $"{i}.{domain}"
  7.  
  8.         var result = ReadDNSTxtResult(fragmentUrl); 
  9.         if (result == null) break;// otherwise parent domain value will be added 
  10.         fragments.Add(result); 
  11.     } 
  12.  
  13.     return string.Join("", fragments); 
  14.  
  15. private string ReadDNSTxtResult(string fragmentUrl) 
  16.     if (!fragmentUrl.EndsWith(".")) 
  17.     { 
  18.         fragmentUrl = fragmentUrl + "."
  19.     } 
  20.     var result = lookup.QueryAsync(fragmentUrl, QueryType.TXT).Result; 
  21.     if (result != null && !result.HasError && result.Answers?.Count > 0 ) 
  22.     { 
  23.         var resultDomain = result.Answers.FirstOrDefault().DomainName.Value; 
  24.         if (resultDomain == fragmentUrl) 
  25.         { 
  26.           return result.Answers.TxtRecords().FirstOrDefault()?.EscapedText.FirstOrDefault(); 
  27.         } 
  28.     } 
  29.     return null

客戶端可以輕松地驗證所獲取的數(shù)據(jù)是否生成密鑰并且是否有效,因為客戶端可以獲取數(shù)據(jù),哈希并比較結果。此外,客戶端可以遞歸驗證以檢查所有父節(jié)點是否都是真實的。這就是驗證過程所要做的。它由下一部分代碼表示:

  1. public List<string> Validate(JObject data, string keyint db, string domain, byte[] privateKey, string expectedKey = null
  2.     var errors = new List<string>(); 
  3.     //ValidateBase: Coherence betweeen data and values
  4.     var computed = this.Get(key, db, domain, privateKey); 
  5.  
  6.     if (key != computed.Hash) 
  7.     { 
  8.         errors.Add("Key mismatch"); 
  9.     } 
  10.  
  11.     ValidateHierarchy(key,db,domain,privateKey, ref errors); 
  12.     return errors; 
  13.  
  14. private List<string> ValidateHierarchy(string  key,   int db, string domain, byte[] privateKey, ref List<string> errors) 
  15.     var computed = this.Get(key, db, domain, privateKey); 
  16.     if (computed == nullreturn new List<string>(); 
  17.  
  18.     if (computed.History.Count > 0) 
  19.     { 
  20.         var hierarchy = ValidateHierarchy(computed.History.Last(), db, domain, privateKey, ref errors); 
  21.         if (hierarchy.Count != computed.History.Count-1) 
  22.         { 
  23.             errors.Add($"{computed.Hash}: history count not match with lookup"); 
  24.         } 
  25.         else 
  26.         { 
  27.             for (int i = 0; i< hierarchy.Count; i++) 
  28.             { 
  29.                 if (hierarchy[i] != computed.History[i]) 
  30.                 { 
  31.                     errors.Add($"{computed.Hash}: history do not match at {computed.History[i]}"); 
  32.                 } 
  33.             } 
  34.         } 
  35.  
  36.     } 
  37.  
  38.     return computed.History.ToList(); 

如您在上一個片段中看到的那樣,將驗證記錄,然后下載所有層次結構并檢查數(shù)據(jù)一致性。

現(xiàn)在我們了解了如何從DNS寫入和讀取數(shù)據(jù),下一步是如何確保它們的安全。

密碼學和密鑰

我們的系統(tǒng)可以向DNS讀取和寫入數(shù)據(jù),現(xiàn)在該注意安全了。我們假設寫給我們的DNS的人是受信任的,但是我們不能確保惡意的DNS服務器不會給我們偽造數(shù)據(jù)或有人不會讀取它(請記住,DNS數(shù)據(jù)是公共的)。

我在這里所做的就是對協(xié)議進行了以下改進:使用非對稱算法對存儲的數(shù)據(jù)進行加密存儲。這樣可以確保只有數(shù)據(jù)生產(chǎn)者才能生成消費者可以理解的數(shù)據(jù)。任何人都可以創(chuàng)建偽造的DNS服務器,但是他們將無法對待您偽造數(shù)據(jù)。而且,數(shù)據(jù)現(xiàn)在已加密,沒有人可以讀取。

非對稱算法是完美的,因為它只允許一定數(shù)量的讀者理解消息,但是只有消息源才能產(chǎn)生消息。為此,客戶端生成一對密鑰。公鑰用于加密數(shù)據(jù),因此生產(chǎn)者可以安全地保護它。與使用者共享用于解密的私鑰。可以手動共享它,例如通過電子郵件將其發(fā)送到加密的存檔中,或者發(fā)布在HTTPS網(wǎng)站上,證書可以在該網(wǎng)站上向用戶展示權限。

順便說一下,這個概念很簡單:現(xiàn)在數(shù)據(jù)已加密,沒有人可以代表我們寫入數(shù)據(jù)。但是還有另一個問題。對稱算法只處理少量數(shù)據(jù)(1024-4096字節(jié)),但我們必須處理巨大的JSON有效負載。我們有兩種方法:

  • 將完整的消息分成小字節(jié)塊,并一一加密/解密它們。
  • 創(chuàng)建一個對稱密鑰,使用生成的密鑰對數(shù)據(jù)加密,然后使用非對稱對對生成的密鑰進行加密。這樣,每個記錄都具有用于加密數(shù)據(jù)的不同對稱密鑰。該密鑰是公開共享的,但只有擁有私有密鑰的人才能使用。

考慮到對所有字節(jié)塊進行編碼的計算量,我使用了第二種解決方案。這將我們帶到下一個有效負載:

  1.    "data":"json object encrypted with the symm key"
  2.    "key":"symm key encripted with the aymm alghorithm" 

在上面的代碼段中,我們可以看到存儲在JSON有效負載中的加密數(shù)據(jù)和解密密鑰。讀取器將使用私鑰解密對稱密鑰,然后將其用于解密數(shù)據(jù)。

代碼中的更改是最小的:所需的只是包裝\展開數(shù)據(jù)的附加步驟。

在下一個代碼段中,我顯示了完成數(shù)據(jù)生成的步驟:

  1. #generate a one time password 
  2. var password = SHA512.Create().ComputeHash(Guid.NewGuid().ToByteArray()); 
  3. #encrypt the password 
  4. var decriptkey = this.cryptoService.EncodeKey(password, publicKey); 
  5. #encrypt data with the password 
  6.  var dataEnrypted = this.cryptoService.EncryptData(dataToEncode, password); 
  7. #json object is stored with decriptkey and dataEnrypted 

在下一個代碼段中,我們具有閱讀過程:

  1. var decriptKeyEncoded = .. from json 
  2. var dataEncrypted = ... from json    
  3. var decriptKey = this.cryptoService.DecodeKey(decriptKeyEncoded, privateKey);  
  4.  
  5. var decodedData = this.cryptoService.DecodeData(dataEncrypted, decriptKey); 
  6. #decodedData is the plain data. 

既然我們已經(jīng)完成了有關區(qū)塊鏈實現(xiàn)的說明,那么我們就擁有了將數(shù)據(jù)存儲在DNS區(qū)塊鏈中的所有詳細信息。

結論

即使將DNS服務器用作數(shù)據(jù)庫看起來似乎很聰明,但事實并非如此。DNS并非旨在以這種方式存儲數(shù)據(jù)。

如果我們必須處理安全的不可變數(shù)據(jù),則解決方案是使用標準的區(qū)塊鏈平臺,我的意思是需要使用一個真正的區(qū)塊鏈系統(tǒng)。

無論如何,嘗試實現(xiàn)無服務器的區(qū)塊鏈非常有趣,我希望它教會了我們區(qū)塊鏈平臺背后的原理。

責任編輯:武曉燕 來源: 區(qū)塊鏈研究實驗室
相關推薦

2021-04-16 20:43:18

Go區(qū)塊鏈編程

2018-05-03 20:55:47

區(qū)塊鏈分布式數(shù)據(jù)庫

2018-05-30 10:31:10

2022-01-10 10:56:37

區(qū)塊鏈技術比特幣

2018-09-27 16:15:10

區(qū)塊鏈數(shù)據(jù)庫

2019-03-14 09:30:35

區(qū)塊鏈數(shù)據(jù)庫存儲

2022-03-08 14:31:37

區(qū)塊鏈汽車技術

2021-12-22 23:28:04

區(qū)塊鏈人工智能技術

2021-03-16 21:39:47

區(qū)塊鏈DEMOGo

2021-03-12 19:17:38

區(qū)塊鏈GoPython

2021-03-17 20:29:36

區(qū)塊鏈DEMOPython

2021-04-09 20:04:34

區(qū)塊鏈Go加密

2021-09-23 22:40:10

區(qū)塊鏈比特幣技術

2018-04-18 17:08:45

2018-02-10 19:12:14

區(qū)塊鏈數(shù)據(jù)庫解決方案

2018-03-27 09:52:30

區(qū)塊鏈數(shù)字貨幣比特幣

2021-10-26 08:56:35

區(qū)塊鏈數(shù)據(jù)庫分類賬

2017-06-28 08:14:57

數(shù)據(jù)庫區(qū)塊鏈比特幣

2024-08-01 13:12:57

2018-08-08 09:50:36

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 色吊丝在线 | 国产精品一区二区在线 | 一级做a爰片性色毛片视频停止 | 黄免费观看视频 | 四虎影视免费观看 | 欧美日韩综合精品 | 国产乱码久久久 | 亚洲一区二区电影在线观看 | 亚洲一级毛片 | 国产美女在线播放 | 毛片av免费看 | 日韩免费中文字幕 | 成年精品 | 日韩在线视频一区二区三区 | 国产91亚洲精品一区二区三区 | 午夜影院在线观看免费 | 亚洲高清一区二区三区 | 国色天香成人网 | 国产清纯白嫩初高生在线播放视频 | 国产精品久久久久久久久久妇女 | 日韩午夜网站 | 日韩在线观看一区二区三区 | 先锋资源网站 | 午夜视频免费在线观看 | 久久精品亚洲 | 91视频大全 | 国产伦精品一区二区三区四区视频 | 中文字幕伊人 | 国产精品久久国产精品99 | 久久精品99久久 | 91视频久久| 成人不卡 | 韩日在线视频 | 国产成人精品一区二区三区四区 | 日韩av一区二区在线观看 | 成人看片在线观看 | 国产精品久久久久久久午夜片 | 在线观看日韩精品视频 | 亚洲精品v | 国产日韩精品一区二区 | 狠狠色香婷婷久久亚洲精品 |