java 比特币私钥生成_如何生成自己的比特币私钥
java 比特幣私鑰生成
In cryptocurrencies, a private key allows a user to gain access to their wallet. The person who holds the private key fully controls the coins in that wallet. For this reason, you should keep it secret. And if you really want to generate the key yourself, it makes sense to generate it in a secure way.
在加密貨幣中,私鑰允許用戶訪問其錢包。 持有私鑰的人可以完全控制該錢包中的硬幣。 因此,您應該對其保密。 而且,如果您真的想自己生成密鑰,則以安全的方式生成密鑰是有意義的。
Here, I will provide an introduction to private keys and show you how you can generate your own key using various cryptographic functions. I will provide a description of the algorithm and the code in Python.
在這里,我將對私鑰進行介紹,并向您展示如何使用各種加密功能生成自己的密鑰。 我將提供Python中的算法和代碼的描述。
我需要生成一個私鑰嗎? (Do I need to generate a private key?)
Most of the time you don’t. For example, if you use a web wallet like Coinbase or Blockchain.info, they create and manage the private key for you. It’s the same for exchanges.
大多數時候你不這樣做。 例如,如果您使用Coinbase或Blockchain.info之類的網絡錢包,它們將為您創建和管理私鑰。 交流是一樣的。
Mobile and desktop wallets usually also generate a private key for you, although they might have the option to create a wallet from your own private key.
移動和臺式機錢包通常還可以為您生成一個私鑰,盡管它們可以選擇根據您自己的私鑰創建一個錢包。
So why generate it anyway? Here are the reasons that I have:
那么為什么要生成它呢? 這是我有的原因:
- You want to make sure that no one knows the key 您要確保沒有人知道鑰匙
- You just want to learn more about cryptography and random number generation (RNG) 您只想了解有關加密和隨機數生成(RNG)的更多信息
私鑰到底是什么? (What exactly is a private key?)
Formally, a private key for Bitcoin (and many other cryptocurrencies) is a series of 32 bytes. Now, there are many ways to record these bytes. It can be a string of 256 ones and zeros (32 * 8 = 256) or 100 dice rolls. It can be a binary string, Base64 string, a WIF key, mnemonic phrase, or finally, a hex string. For our purposes, we will use a 64 character long hex string.
正式而言,比特幣(和許多其他加密貨幣)的私鑰是一系列的32個字節。 現在,有很多方法可以記錄這些字節。 它可以是256個1和0(32 * 8 = 256)或100個骰子骰的字符串。 它可以是二進制字符串,Base64字符串, WIF鍵 , 助記詞或最后一個十六進制字符串。 為了我們的目的,我們將使用64個字符的十六進制字符串。
Why exactly 32 bytes? Great question! You see, to create a public key from a private one, Bitcoin uses the ECDSA, or Elliptic Curve Digital Signature Algorithm. More specifically, it uses one particular curve called secp256k1.
為什么是32個字節? 好問題! 您會看到,為了從私鑰創建公鑰,比特幣使用ECDSA或橢圓曲線數字簽名算法。 更具體地說,它使用一條稱為secp256k1的特定曲線。
Now, this curve has an order of 256 bits, takes 256 bits as input, and outputs 256-bit integers. And 256 bits is exactly 32 bytes. So, to put it another way, we need 32 bytes of data to feed to this curve algorithm.
現在,該曲線的階數為256位,以256位為輸入,并輸出256位整數。 256位恰好是32個字節。 因此,換句話說,我們需要32字節的數據才能饋入此曲線算法。
There is an additional requirement for the private key. Because we use ECDSA, the key should be positive and should be less than the order of the curve. The order of secp256k1 is FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141, which is pretty big: almost any 32-byte number will be smaller than it.
私鑰還有其他要求。 由于我們使用ECDSA,因此關鍵點應為正,并且應小于曲線的階數。 secp256k1的順序為FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 ,它的大小非常大:幾乎所有32字節的數字都小于它。
天真的方法 (Naive method)
So, how do we generate a 32-byte integer? The first thing that comes to mind is to just use an RNG library in your language of choice. Python even provides a cute way of generating just enough bits:
那么,我們如何生成一個32字節的整數? 首先想到的是只使用您選擇的語言使用RNG庫。 Python甚至提供了一種可愛的方式來生成足夠的位:
import random bits = random.getrandbits(256) # 30848827712021293731208415302456569301499384654877289245795786476741155372082 bits_hex = hex(bits) # 0x4433d156e8c53bf5b50af07aa95a29436f29a94e0ccc5d58df8e57bdc8583c32 private_key = bits_hex[2:] # 4433d156e8c53bf5b50af07aa95a29436f29a94e0ccc5d58df8e57bdc8583c32Looks good, but actually, it’s not. You see, normal RNG libraries are not intended for cryptography, as they are not very secure. They generate numbers based on a seed, and by default, the seed is the current time. That way, if you know approximately when I generated the bits above, all you need to do is brute-force a few variants.
看起來不錯,但實際上并非如此。 您會看到,普通的RNG庫不是用于加密,因為它們不是很安全。 它們根據種子生成數字,默認情況下,種子是當前時間。 這樣,如果您大概知道我何時生成了上面的位,那么您所要做的就是蠻力地制造一些變體。
When you generate a private key, you want to be extremely secure. Remember, if anyone learns the private key, they can easily steal all the coins from the corresponding wallet, and you have no chance of ever getting them back.
當您生成私鑰時,您希望非常安全。 請記住,如果有人學習了私鑰,他們可以輕松地從相應的錢包中竊取所有硬幣,并且您將永遠沒有機會將它們取回。
So let’s try to do it more securely.
因此,讓我們嘗試更安全地進行操作。
具有加密功能的RNG (Cryptographically strong RNG)
Along with a standard RNG method, programming languages usually provide a RNG specifically designed for cryptographic operations. This method is usually much more secure, because it draws entropy straight from the operating system. The result of such RNG is much harder to reproduce. You can’t do it by knowing the time of generation or having the seed, because there is no seed. Well, at least the user doesn’t enter a seed — rather, it’s created by the program.
與標準RNG方法一起,編程語言通常會提供專門為密碼操作設計的RNG。 這種方法通常更安全,因為它直接從操作系統中獲取熵。 這種RNG的結果很難復制。 您無法通過知道生成時間或擁有種子來做到這一點,因為沒有種子。 好吧,至少用戶沒有輸入種子,而是由程序創建的。
In Python, cryptographically strong RNG is implemented in the secrets module. Let’s modify the code above to make the private key generation secure!
在Python中, secrets模塊中實現了具有加密功能的RNG。 讓我們修改上面的代碼以確保私鑰生成的安全!
import secrets bits = secrets.randbits(256) # 46518555179467323509970270980993648640987722172281263586388328188640792550961 bits_hex = hex(bits) # 0x66d891b5ed7f51e5044be6a7ebe4e2eae32b960f5aa0883f7cc0ce4fd6921e31 private_key = bits_hex[2:] # 66d891b5ed7f51e5044be6a7ebe4e2eae32b960f5aa0883f7cc0ce4fd6921e31That is amazing. I bet you wouldn’t be able to reproduce this, even with access to my PC. But can we go deeper?
這是驚人的。 我敢打賭,即使使用我的電腦,您也將無法重現此內容。 但是我們可以更深入嗎?
專業網站 (Specialized sites)
There are sites that generate random numbers for you. We will consider just two here. One is random.org, a well-known general purpose random number generator. Another one is bitaddress.org, which is designed specifically for Bitcoin private key generation.
有些網站會為您生成隨機數。 我們這里只考慮兩個。 一個是random.org ,這是眾所周知的通用隨機數生成器。 另一個是bitaddress.org ,它是專門為生成比特幣私鑰而設計的。
Can random.org help us generate a key? Definitely, as they have service for generating random bytes. But two problems arise here. Random.org claims to be a truly random generator, but can you trust it? Can you be sure that it is indeed random? Can you be sure that the owner doesn’t record all generation results, especially ones that look like private keys? The answer is up to you. Oh, and you can’t run it locally, which is an additional problem. This method is not 100% secure.
random.org可以幫助我們生成密鑰嗎? 當然,因為他們的服務生成隨機字節。 但是這里出現兩個問題。 Random.org聲稱是真正的隨機生成器,但是您可以信任它嗎? 您可以確定它確實是隨機的嗎? 您可以確定所有者不會記錄所有生成結果,尤其是看起來像私鑰的結果嗎? 答案取決于您。 哦,您不能在本地運行它,這是另一個問題。 此方法不是100%安全的。
Now, bitaddress.org is a whole different story. It’s open source, so you can see what’s under its hood. It’s client-side, so you can download it and run it locally, even without an Internet connection.
現在, bitaddress.org是一個完全不同的故事。 它是開源的,因此您可以看到它的內幕。 它是客戶端,因此即使沒有Internet連接,也可以下載并在本地運行。
So how does it work? It uses you — yes, you — as a source of entropy. It asks you to move your mouse or press random keys. You do it long enough to make it infeasible to reproduce the results.
那么它是怎樣工作的? 它使用您(是的,您)作為熵的來源。 它要求您移動鼠標或按隨機鍵。 您所做的時間足夠長,以致無法再現結果。
Are you interested to see how bitaddress.org works? For educational purposes, we will look at its code and try to reproduce it in Python.
您是否有興趣查看bitaddress.org的工作原理? 出于教育目的,我們將查看其代碼并嘗試在Python中重現它。
Quick note: bitaddress.org gives you the private key in a compressed WIF format, which is close to the WIF format that we discussed before. For our purposes, we will make the algorithm return a hex string so that we can use it later for a public key generation.
快速說明:bitaddress.org為您提供壓縮WIF格式的私鑰,該私鑰與我們之前討論的WIF格式相似。 出于我們的目的,我們將使算法返回一個十六進制字符串,以便以后可以將其用于生成公共密鑰。
位地址:詳細信息 (Bitaddress: the specifics)
Bitaddress creates the entropy in two forms: by mouse movement and by key pressure. We’ll talk about both, but we’ll focus on the key presses, as it’s hard to implement mouse tracking in the Python lib. We’ll expect the end user to type buttons until we have enough entropy, and then we’ll generate a key.
位地址以兩種形式創建熵:通過鼠標移動和通過按鍵。 我們將討論兩者,但我們將重點放在按鍵上,因為很難在Python庫中實現鼠標跟蹤。 我們希望最終用戶鍵入按鈕,直到我們有足夠的熵,然后再生成一個鍵。
Bitaddress does three things. It initializes byte array, trying to get as much entropy as possible from your computer, it fills the array with the user input, and then it generates a private key.
位地址可做三件事。 它初始化字節數組,嘗試從您的計算機中獲取盡可能多的熵,并用用戶輸入填充該數組,然后生成一個私鑰。
Bitaddress uses the 256-byte array to store entropy. This array is rewritten in cycles, so when the array is filled for the first time, the pointer goes to zero, and the process of filling starts again.
位地址使用256字節數組存儲熵。 該數組將以周期重寫,因此,第一次填充該數組時,指針將變為零,并且填充過程將再次開始。
The program initiates an array with 256 bytes from window.crypto. Then, it writes a timestamp to get an additional 4 bytes of entropy. Finally, it gets such data as the size of the screen, your time zone, information about browser plugins, your locale, and more. That gives it another 6 bytes.
該程序從window.crypto啟動一個具有256個字節的數組。 然后,它編寫一個時間戳以獲取額外的4個字節的熵。 最后,它獲得諸如屏幕大小,您的時區,有關瀏覽器插件的信息,您的語言環境等信息。 這又給了它6個字節。
After the initialization, the program continually waits for user input to rewrite initial bytes. When the user moves the cursor, the program writes the position of the cursor. When the user presses buttons, the program writes the char code of the button pressed.
初始化之后,程序將繼續等待用戶輸入以重寫初始字節。 當用戶移動光標時,程序將寫入光標的位置。 當用戶按下按鈕時,程序將寫入所按下按鈕的字符代碼。
Finally, bitaddress uses accumulated entropy to generate a private key. It needs to generate 32 bytes. For this task, bitaddress uses an RNG algorithm called ARC4. The program initializes ARC4 with the current time and collected entropy, then gets bytes one by one 32 times.
最后,位地址使用累積的熵來生成私鑰。 它需要生成32個字節。 對于此任務,位地址使用稱為ARC4的RNG算法。 該程序將使用當前時間初始化ARC4并收集熵,然后將字節1乘以32。
This is all an oversimplification of how the program works, but I hope that you get the idea. You can check out the algorithm in full detail on Github.
這一切都過于簡化了程序的工作方式,但是我希望您能理解。 您可以在Github上詳細了解算法。
自己動手 (Doing it yourself)
For our purposes, we’ll build a simpler version of bitaddress. First, we won’t collect data about the user’s machine and location. Second, we will input entropy only via text, as it’s quite challenging to continually receive mouse position with a Python script (check PyAutoGUI if you want to do that).
為了我們的目的,我們將構建一個更簡單的bitaddress版本。 首先,我們不會收集有關用戶機器和位置的數據。 其次,我們將僅通過文本輸入熵,因為使用Python腳本連續接收鼠標位置非常困難(如果要這樣做,請檢查PyAutoGUI )。
That brings us to the formal specification of our generator library. First, it will initialize a byte array with cryptographic RNG, then it will fill the timestamp, and finally it will fill the user-created string. After the seed pool is filled, the library will let the developer create a key. Actually, they will be able to create as many private keys as they want, all secured by the collected entropy.
這使我們成為生成器庫的正式規范。 首先,它將使用加密的RNG初始化字節數組,然后將填充時間戳,最后將填充用戶創建的字符串。 種子池填滿后,庫將允許開發人員創建密鑰。 實際上,他們將能夠根據需要創建任意數量的私鑰,全部由收集的熵保護。
初始化池 (Initializing the pool)
Here we put some bytes from cryptographic RNG and a timestamp. __seed_int and __seed_byte are two helper methods that insert the entropy into our pool array. Notice that we use secrets.
在這里,我們從加密RNG和時間戳中放入了一些字節。 __seed_int和__seed_byte是兩個將熵插入到我們的池數組中的輔助方法。 注意,我們使用secrets 。
def __init_pool(self):for i in range(self.POOL_SIZE):random_byte = secrets.randbits(8)self.__seed_byte(random_byte)time_int = int(time.time())self.__seed_int(time_int) def __seed_int(self, n):self.__seed_byte(n)self.__seed_byte(n >> 8)self.__seed_byte(n >> 16)self.__seed_byte(n >> 24) def __seed_byte(self, n):self.pool[self.pool_pointer] ^= n & 255self.pool_pointer += 1if self.pool_pointer >= self.POOL_SIZE:self.pool_pointer = 0輸入播種 (Seeding with input)
Here we first put a timestamp and then the input string, character by character.
在這里,我們首先放置一個時間戳,然后逐個字符地輸入字符串。
def seed_input(self, str_input):time_int = int(time.time())self.__seed_int(time_int)for char in str_input:char_code = ord(char)self.__seed_byte(char_code)生成私鑰 (Generating the private key)
This part might look hard, but it’s actually very simple.
這部分可能很難看,但實際上非常簡單。
First, we need to generate 32-byte number using our pool. Unfortunately, we can’t just create our own random object and use it only for the key generation. Instead, there is a shared object that is used by any code that is running in one script.
首先,我們需要使用我們的池生成32字節的數字。 不幸的是,我們不能僅僅創建自己的random對象并將其僅用于密鑰生成。 而是有一個共享對象,供一個腳本中運行的任何代碼使用。
What does that mean for us? It means that at each moment, anywhere in the code, one simple random.seed(0) can destroy all our collected entropy. We don’t want that. Thankfully, Python provides getstate and setstate methods. So, to save our entropy each time we generate a key, we remember the state we stopped at and set it next time we want to make a key.
這對我們意味著什么? 這意味著在代碼的任何地方,每個時刻,一個簡單的random.seed(0)都會破壞我們收集的所有熵。 我們不想要那個。 幸運的是,Python提供了getstate和setstate方法。 因此,為了在每次生成密鑰時保存熵,我們會記住停下來的狀態,并在下次要創建密鑰時進行設置。
Second, we just make sure that our key is in range (1, CURVE_ORDER). This is a requirement for all ECDSA private keys. The CURVE_ORDER is the order of the secp256k1 curve, which is FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141.
其次,我們只需確保我們的密鑰在范圍內(1, CURVE_ORDER )。 這是所有ECDSA私鑰的要求。 CURVE_ORDER是secp256k1曲線的順序,即FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 。
Finally, for convenience, we convert to hex, and strip the ‘0x’ part.
最后,為方便起見,我們將其轉換為十六進制,并去除“ 0x”部分。
def generate_key(self):big_int = self.__generate_big_int()big_int = big_int % (self.CURVE_ORDER — 1) # key < curve orderbig_int = big_int + 1 # key > 0key = hex(big_int)[2:]return key def __generate_big_int(self):if self.prng_state is None:seed = int.from_bytes(self.pool, byteorder=’big’, signed=False)random.seed(seed)self.prng_state = random.getstate()random.setstate(self.prng_state)big_int = random.getrandbits(self.KEY_BYTES * 8)self.prng_state = random.getstate()return big_int在行動 (In action)
Let’s try to use the library. Actually, it’s really simple: you can generate a private key in three lines of code!
讓我們嘗試使用該庫。 實際上,這非常簡單:您可以用三行代碼生成一個私鑰!
kg = KeyGenerator() kg.seed_input(‘Truly random string. I rolled a dice and got 4.’) kg.generate_key() # 60cf347dbc59d31c1358c8e5cf5e45b822ab85b79cb32a9f3d98184779a9efc2You can see it yourself. The key is random and totally valid. Moreover, each time you run this code, you get different results.
您可以自己查看。 密鑰是隨機的,并且完全有效。 而且,每次運行此代碼,您都會得到不同的結果。
結論 (Conclusion)
As you can see, there are a lot of ways to generate private keys. They differ in simplicity and security.
如您所見,有很多生成私鑰的方法。 它們在簡單性和安全性方面有所不同。
Generating a private key is only a first step. The next step is extracting a public key and a wallet address that you can use to receive payments. The process of generating a wallet differs for Bitcoin and Ethereum, and I plan to write two more articles on that topic.
生成私鑰只是第一步。 下一步是提取可用于接收付款的公鑰和錢包地址。 比特幣和以太坊生成錢包的過程有所不同,我計劃就該主題再寫兩篇文章。
If you want to play with the code, I published it to this Github repository.
如果您想使用這些代碼,我將其發布到了這個Github倉庫 。
I am making a course on cryptocurrencies here on freeCodeCamp News. The first part is a detailed description of the blockchain.
我正在freeCodeCamp News上開設有關加密貨幣的課程。 第一部分是對區塊鏈的詳細描述。
I also post random thoughts about crypto on Twitter, so you might want to check it out.
我還在Twitter上發布了關于加密的隨機想法,因此您可能需要檢查一下。
翻譯自: https://www.freecodecamp.org/news/how-to-generate-your-very-own-bitcoin-private-key-7ad0f4936e6c/
java 比特幣私鑰生成
總結
以上是生活随笔為你收集整理的java 比特币私钥生成_如何生成自己的比特币私钥的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 周公解梦梦到玉米棒子是什么意思
- 下一篇: 女人梦到大粪是什么预兆
