提出了一種以58字符 Base58Check編碼的可打印字符串的形式對密碼保密型私鑰記錄進行加密和編碼的方法。加密私鑰記錄旨在用於紙質錢包。每個記錄字符串都包含除了密碼以外重構私鑰所需的全部信息,而且該方法使用加鹽和scrypt來抵抗暴力攻擊。git
密碼和密碼保護型密鑰是我的間發送資產的新實踐。想要發送資產的人能夠經過郵政郵件郵寄一個受密碼保護的紙錢包並經過電話或者email給接收者密碼,以保證傳遞的安全不受其餘通道的攔截。紙錢包的使用者能夠攜帶資金的加密私鑰並在家中留存一份拷貝以預防意外的遺失和偷竊。把資產存在銀行帳戶或者保險箱中的紙錢包的用戶能夠把密碼留在家裏或者與可信的夥伴分享已預防銀行中的某人伺機訪問紙錢包並花費其中的資產。預見和不可預見的關於密碼保護型私鑰的用例還有不少。
另外一方面,標準的密碼保護型私鑰格式使得其可以共享來自不一樣錢包客戶端的私鑰。github
用例:做爲一個NEO紙錢包用戶,我喜歡添加加密的功能,如此個人NEO紙錢包能夠拆解成兩個因子:我有的和我知道的。
用例:做爲一個NEO用戶想要用一個私鑰向我的或者公司付款,我沒必要擔憂任何通訊渠道會攔截個人key和致使資產的被盜。我想要提供一個密碼保護型密鑰,伴隨一個能夠經過其餘渠道傳輸的密碼。算法
本提議運用到了如下函數和定義:
·AES256加密、AES256解密,是衆所周知的AES分組編碼不考慮初始向量和塊鏈接的簡單格式。這些函數每個都須要一個256位的key和16字節的輸入和肯定的16字節的輸出。
·SHA256,一種衆所周知的任意字節長度輸入和固定產出32字節長度hash的哈希算法。
·scrypt,一個著名的密鑰推導算法。它須要如下參數(string) password, (string) salt, (int) n, (int) r, (int) p, (int) length,並固定產生一個長度等於length長度的字節數組。
Base58Check,一個在NEO系統中普遍使用的用58的字符byte[]編碼的方法。數組
建議將Base58Check編碼事後的字符串以6字開頭。數字6旨在從用戶的角度表示一種須要其餘東西才能生效的私鑰–總的定義能夠理解爲未來包括特別是在多籤交易中的密鑰,而且被選聽從現有前綴5,多見於WIF格式表示一種非加密私鑰。
建議第二個字符應該給出提示所需什麼因子,對於加密密鑰須要一個密碼,建議使用大寫字母P。
爲保持加密密鑰的大小,在AES加密中不使用初始向量(IVS)。相反,使用scrypt從密碼以及NEO地址的32位hash做爲鹽導出用於相似初始向量用途的合適值。安全
對象標識符前綴:0x0142。這是在Base58Check編碼記錄開頭的常量字節,它們的存在致使結果字符串具備可預見的前綴。
用戶如何判斷:58個字符老是以「6P」開頭
有效載荷字節數(不包括前綴):37
·1字節(FLAG字節):始終爲0xE0
·4字節:Sha256(Sha256(expected_neo_address))[0…3]),用於拼寫檢查和加鹽。
16字節:AES加密密鑰材料記錄(加密半數1)
16字節:AES加密密鑰材料記錄(加密半數2)
在BASE58CHECK編碼(前綴6Py)中的範圍:
最小值:6PYJXKPVNKXUZAFD2B5ZSZAFJYNP4EZQQECJS39 449 QUUXLNXJLX6LG(基於01 42 E0加三十六個00)
最大值:6PyxG5TnGyLyxDrZiqxBuxxdotBNTBI3D61MQBXPPZQZEJTVQQHSCNK(基於01 42 E0加三十六個FF)ssh
一、計算NEO地址(ASCII),
並獲取SHA256(SHA256())的前四個字節.咱們將其叫作地址哈希。
2.使用Scrypt從密碼導出一個密鑰。
·參數:密碼是以UTF-8格式的密碼。鹽採用以前獲得的地址hash,n=16384,r=8,p=8,length=64
·把結果的64字節分紅2半,稱他們爲導出半數1和導出半數2.
3.作AES256加密(block = privkey[0…15] xor derivedhalf1[0…15], key = derivedhalf2),把16字節的結果叫作加密半數1.
4.作AES256加密(block = privkey[16…31] xor derivedhalf1[16…31], key = derivedhalf2),把16字節的結果叫作加密半數2.
加密私鑰是如下Base58Check編碼下的串聯,總共39字節,沒有Base58 checksum:
·0x01 0x42 + flagbyte + addresshash + encryptedhalf1 + encryptedhalf2函數
1.從用戶那獲取加密私鑰和密碼。
2.把密碼和地址hash帶入Scrypt函數獲得半導出數1和半導出數2.
3.用AES256Decrypt解密半導出數1和半導出數2,併合並兩部分並將結果和半導出數1作異或獲得明文形式私鑰。
4.把明文私鑰轉化成NEO地址。
5.求NEO地址hash,並驗證加密私鑰記錄中的地址hash是否與之匹配。若是不是,則報告密碼錯誤。測試
向後兼容性是最小的,因爲它是一種新標準幾乎擴展了WIF格式。假設私鑰數據的入口能夠接受現存格式的私鑰(好比16進制數或者WIF格式);本草案使用的密鑰格式不能被錯誤地用於任何現有的格式,並保留自動檢測能力。編碼
Test 1:
• Passphrase: TestingOneTwoThree
• Encrypted: 6PYVPVe1fQznphjbUxXP9KZJqPMVnVwCx5s5pr5axRJ8uHkMtZg97eT5kL
• Unencrypted (WIF): L44B5gGEpqEDRS9vVPz7QT35jcBG2r3CZwSwQ4fCewXAhAhqGVpP
• Unencrypted (hex): CBF4B9F70470856BB4F40F80B87EDB90865997FFEE6DF315AB166D713AF433A5
Test 2:
• Passphrase: Satoshi
• Encrypted: 6PYN6mjwYfjPUuYT3Exajvx25UddFVLpCw4bMsmtLdnKwZ9t1Mi3CfKe8S
• Unencrypted (WIF): KwYgW8gcxj1JWJXhPSu4Fqwzfhp5Yfi42mdYmMa4XqK7NJxXUSK7
• Unencrypted (hex): 09C2686880095B1A4C249EE3AC4EEA8A014F11E6F986D0B5025AC1F39AFBD9AE加密
• neo-project/neo: github.com/neo-project…
• CityOfZion/neon-js: github.com/CityOfZion/…
原文:來自 github.com/neo-project…