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:]
# 4433d156e8c53bf5b50af07aa95a29436f29a94e0ccc5d58df8e57bdc8583c32

Looks 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:]
# 66d891b5ed7f51e5044be6a7ebe4e2eae32b960f5aa0883f7cc0ce4fd6921e31

That 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提供了getstatesetstate方法。 因此,为了在每次生成密钥时保存熵,我们会记住停下来的状态,并在下次要创建密钥时进行设置。

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()
# 60cf347dbc59d31c1358c8e5cf5e45b822ab85b79cb32a9f3d98184779a9efc2

You 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 比特币私钥生成_如何生成自己的比特币私钥相关推荐

  1. java随机数带字母_随机生成一组随机数(带字母和数字)

    随机生成一组随机数(带字母和数字) package com.qfx.util; import java.util.Random; public class CharacterUtils { // 得到 ...

  2. java开发防伪码_企业编码生成系统智能批量生成带数据分析功能的防伪码

    一 代码 # 生成含数据分析功能防伪编码函数,参数schoice设置输出的文件名称 def scode5(schoice): default_dir = r"mrsoft.mri" ...

  3. tea 加密密钥生成_加密密钥生成需要的是熵的良好来源

    tea 加密密钥生成 想象一下,您要玩涉及使用骰子的棋盘游戏,例如专卖,Yahtzee,Cluedo,Dungeons&Dragons ... 1在大多数情况下,至少在您对玩公平游戏感兴趣的地 ...

  4. 小程序 formid 生成_在线生成在线制作配音小程序

    输入文字,生成声音--在线用文字制作声音文件. 有男声.女声.童声.方言和英语,应有尽有,语音效果自然流畅. 在线配音生成器,无需下载安装,直接在线即可生成配音文件,你可以用于抖音快手等短视频里面的配 ...

  5. java工程license机制_使用truelicense实现用于JAVA工程license机制(包括license生成和验证)...

    开发的软件产品在交付使用的时候,往往会授权一段时间的试用期,这个时候license就派上用场了.不同于在代码中直接加上时间约束,需要重新授权的时候使用license可以避免修改源码,改动部署,授权方直 ...

  6. 【可食用】KeyTool生成KeyStore,证书、公钥、私钥文档JAVA生成,JAVA实现ECC签名验签

    KeyTool生成KeyStore,证书.公钥.私钥文档JAVA生成,JAVA实现ECC签名验签 一.首先我们可以写个工具类生成密钥对.证书.公钥.私钥文本 jksAndCerGenerator.ja ...

  7. 用java写ods系统_基于数据库的代码自动生成工具,生成JavaBean、生成数据库文档、生成前后端代码等(TableGo v7.0.0版)...

    TableGo是基于数据库的代码自动生成工具,低代码编程技术的实现,可以零代码自动生成SpringBoot项目工程.生成JavaBean.生成前后端分离的CRUD代码.生成MyBaits的Mapper ...

  8. apache poi使用例_使用java Apache poi 根据word模板生成word报表例子

    [实例简介] 使用java Apache poi 根据word模板生成word报表 仅支持docx格式的word文件,大概是word2010及以后版本,doc格式不支持. 使用说明:https://b ...

  9. java生成iso9660工具_基于数据库的代码自动生成工具,生成JavaBean、生成数据库文档、生成前后端代码等(TableGo v7.0.0版)...

    TableGo_20210212 v7.0.0 正式版发布,此次版本更新如下: 1.新增对DB2数据库的支持 2.新增按字段生成文件,支持把字段.JSON.XML数据转换成任何代码 3.新增大量新的自 ...

最新文章

  1. 轻量级UML工具-UMLet
  2. python读取文件多行内容-使用python读取.text文件特定行的数据方法
  3. Spring boot定制错误数据携带出去
  4. 软件设计模式—面向接口编程
  5. mbp网速很慢_苹果笔记本上网很慢怎么回事?macbook无线上网慢的解决方法
  6. Prototype(原型原型链)
  7. c ++中字符串长度的_C ++中的字符串长度
  8. Lync Server 2010迁移至Lync Server 2013部署系列 Part13:DNS记录变更
  9. 关于laravel报错Class 'Barryvdh\Debugbar\ServiceProvider' not found
  10. cadence的工艺角仿真、蒙特卡洛仿真、PSRR
  11. 海康威视提前批-大数据算法工程师面试
  12. 破解版XMind图文安装教程
  13. 《仿大众点评仿美团做一个评价网站——Java SSM》项目研发阶段性总结
  14. html5中图片热点,HTML5 创建热点图
  15. Pinbox 使用快捷键打开网页
  16. ios支付宝支付--看我就够了
  17. 简单处理Ubuntu无法联网的问题
  18. mysqlcount效率,总结到位
  19. surface pro 4 发热抖屏的解决方法
  20. ACM-ICPC 2018 南京赛区网络预赛 I.Skr(Manacher马拉车+Hash哈希/回文树)

热门文章

  1. 7年老Android一次操蛋的面试经历,深度好文
  2. 美团Android开发工程师岗位职能要求,真香
  3. php 静态方法特点,浅析php静态方法与非静态方法的用法区别
  4. jQuery学习笔记(二)—— 操作DOM元素
  5. erlang下lists模块sort(排序)方法源码解析(二)
  6. python的赋值与参数传递(python和linux切换)
  7. Oracle使用hs odbc连接mssql2008
  8. 20145206邹京儒《网络对抗》逆向及Bof基础实践
  9. SQL中的事物【转】
  10. SQL 必知必会·笔记14更新和删除数据