如何根据私钥验证 .Onion 域
How to verify a .Onion domain against a private key
我正在从事一个主要销售 .Onion (TOR) 域名的项目。
生成域的过程类似于挖掘比特币 - RSA 私钥是大量生成的,如果一个随机匹配我的单词列表中的某些内容 - 然后它会被保存在某个地方并添加到数据库中。
这里的问题是,这仍然是一个单独进行的缓慢过程 - 所以为了让我尝试让它成为一个协作练习 - 我想创建一个在线 API / 休息 API 这将允许人们上传他们的域名和私钥,以便他们在网站上销售。
问题是 - 我不太清楚如何根据私钥验证他们的域名。
例如:
他们会提供像
这样的域名
abcdabcdabcdabcd.onion
关键是:
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCb+wlPxR8VoUJsYcEFsPX+LfB3jorW9QlH1N38itQvMs0RyTCB
+c7hfYQH2f8Z67lobWvveYct51ykhB8n3AluMYIF3OxGlmQJuMIFQmKFryLexzPj
LEPREB7+KmeL9Sx1sL4a2Z0qJL4501Ij0T5C3cDEMOvUQBpBttpuUbj1RQIEZTIY
AQKBgBwWDEMOYKaSO17xJRuf32CDYJcDKtkJ1GlWROHxREo68J+74DqF55rnoYl/
4OkfjUMA2WjjjASVRmviBD79vni3eB9MFNzDEMOYa6EIyo1vDEMOzEnfrszkPGEj
vOCHbDiG/FlZsCKsADEMOEAuAUQ3W8669Du4FrO9/al+1IudhAkEAy+KBk8HFsO8Z
UttdlsLt8//l+NbEMmWF/I588EGyYWUuPUVJd5Xv6iSaDMdecjeW/xf4Wja5C91n
lCfb/lxhsQJBAMPZ2fzcUpyKhk6JretSyoq0iVQCO5Pn/0QwTwRUbKreXnnVBYY+
uco2ocfRwsmVK4LUwPgict5qw10bZfl8vdUCQATUV/S0zNc+DEMOw/7p5oJk5hwa
+Hrhcf5aVw1AOqySGs0e9V+qDYIjrbkg/BDEMOD00bTTV9a9h3poFrm+DEMOQF2t
lgqYbgDEMOZbE+PgebFB6swKfx9Px7+PnNsBK+Mld6pRyldfQ2DEMOr/cy4JQDYA
oyX51SNWUMJzkYgeMEUCQQC8i6b3e06B9+++NGADEMO9F5KhlDr1wwSQqnNccDX5
N5vnlhJ/0DGxIMm/bP1ZPUK4/bmvKjNYd7D8zuz2cPor
-----END RSA PRIVATE KEY-----
有人能给我指出一些可以获取私钥并验证所提供的域是否真实的 .Net 代码的方向吗?
https://github.com/lachesis/scallion
这个 github 项目(我使用的工具之一 - 具有 'generate' 域和私钥的代码 - 我只是不确定事后如何执行验证)
对此从未得到答案,但我确实找到了一种方法,在源代码上使用 Scallions 来验证针对洋葱地址的私钥。
RSAWrapper rsaWrapper = new RSAWrapper("d:\pk.txt");
Console.WriteLine(rsaWrapper.OnionHash);
不理想 - 因为它需要私钥。
在 RSAWrapper 内部 - 它执行一些不安全的代码来对 public 键执行 'something' 以确定 DER 编码值。
这是获取洋葱地址的重要部分。
public string OnionHash
{
get {
return tobase32str(this.get_der_hash(),10);
}
}
private byte[] get_der_hash()
{
var sha1 = new System.Security.Cryptography.SHA1Managed();
return sha1.ComputeHash(this.DER);
//return tobase32str(hash);
}
public byte[] DER {
get {
byte[] der;
int buf_size = Rsa.Size + 100;
int size = 0;
unsafe // must be a better way to do this!
{
IntPtr hglob = Marshal.AllocHGlobal(buf_size);
void* ptr = hglob.ToPointer();
void** ptr2 = &ptr;
size = Native.i2d_RSAPublicKey(Rsa.Handle, (byte**)ptr2);
if(size > buf_size)
throw new IndexOutOfRangeException("DER was too large!");
der = new byte[size];
Marshal.Copy(hglob,der,0,size);
Marshal.FreeHGlobal(hglob);
}
return der;
}
}
编辑 - Woot :
看起来 RSAWrapper class 非常具有凝聚力和模块化。
我能够将它复制出来——它只需要访问 OpenSSL 库,它还有一个 RSA.FromPublicKey(string s);创建 RSA 的方法。
所以现在,我可以做到
RSAWrapper rsaWrapper = new RSAWrapper("d:\pubkey.txt", true);
Console.WriteLine(rsaWrapper.OnionHash);
花了几个月的时间 - 但得到了比我打算得到的更好的答案。
现在我可以使用 public 键,并验证洋葱地址是否与 public 键匹配。这将验证洋葱地址的所有权,而无需通过网络发送私钥的风险。
我正在从事一个主要销售 .Onion (TOR) 域名的项目。 生成域的过程类似于挖掘比特币 - RSA 私钥是大量生成的,如果一个随机匹配我的单词列表中的某些内容 - 然后它会被保存在某个地方并添加到数据库中。
这里的问题是,这仍然是一个单独进行的缓慢过程 - 所以为了让我尝试让它成为一个协作练习 - 我想创建一个在线 API / 休息 API 这将允许人们上传他们的域名和私钥,以便他们在网站上销售。
问题是 - 我不太清楚如何根据私钥验证他们的域名。
例如: 他们会提供像
这样的域名abcdabcdabcdabcd.onion
关键是:
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCb+wlPxR8VoUJsYcEFsPX+LfB3jorW9QlH1N38itQvMs0RyTCB
+c7hfYQH2f8Z67lobWvveYct51ykhB8n3AluMYIF3OxGlmQJuMIFQmKFryLexzPj
LEPREB7+KmeL9Sx1sL4a2Z0qJL4501Ij0T5C3cDEMOvUQBpBttpuUbj1RQIEZTIY
AQKBgBwWDEMOYKaSO17xJRuf32CDYJcDKtkJ1GlWROHxREo68J+74DqF55rnoYl/
4OkfjUMA2WjjjASVRmviBD79vni3eB9MFNzDEMOYa6EIyo1vDEMOzEnfrszkPGEj
vOCHbDiG/FlZsCKsADEMOEAuAUQ3W8669Du4FrO9/al+1IudhAkEAy+KBk8HFsO8Z
UttdlsLt8//l+NbEMmWF/I588EGyYWUuPUVJd5Xv6iSaDMdecjeW/xf4Wja5C91n
lCfb/lxhsQJBAMPZ2fzcUpyKhk6JretSyoq0iVQCO5Pn/0QwTwRUbKreXnnVBYY+
uco2ocfRwsmVK4LUwPgict5qw10bZfl8vdUCQATUV/S0zNc+DEMOw/7p5oJk5hwa
+Hrhcf5aVw1AOqySGs0e9V+qDYIjrbkg/BDEMOD00bTTV9a9h3poFrm+DEMOQF2t
lgqYbgDEMOZbE+PgebFB6swKfx9Px7+PnNsBK+Mld6pRyldfQ2DEMOr/cy4JQDYA
oyX51SNWUMJzkYgeMEUCQQC8i6b3e06B9+++NGADEMO9F5KhlDr1wwSQqnNccDX5
N5vnlhJ/0DGxIMm/bP1ZPUK4/bmvKjNYd7D8zuz2cPor
-----END RSA PRIVATE KEY-----
有人能给我指出一些可以获取私钥并验证所提供的域是否真实的 .Net 代码的方向吗? https://github.com/lachesis/scallion 这个 github 项目(我使用的工具之一 - 具有 'generate' 域和私钥的代码 - 我只是不确定事后如何执行验证)
对此从未得到答案,但我确实找到了一种方法,在源代码上使用 Scallions 来验证针对洋葱地址的私钥。
RSAWrapper rsaWrapper = new RSAWrapper("d:\pk.txt");
Console.WriteLine(rsaWrapper.OnionHash);
不理想 - 因为它需要私钥。 在 RSAWrapper 内部 - 它执行一些不安全的代码来对 public 键执行 'something' 以确定 DER 编码值。 这是获取洋葱地址的重要部分。
public string OnionHash
{
get {
return tobase32str(this.get_der_hash(),10);
}
}
private byte[] get_der_hash()
{
var sha1 = new System.Security.Cryptography.SHA1Managed();
return sha1.ComputeHash(this.DER);
//return tobase32str(hash);
}
public byte[] DER {
get {
byte[] der;
int buf_size = Rsa.Size + 100;
int size = 0;
unsafe // must be a better way to do this!
{
IntPtr hglob = Marshal.AllocHGlobal(buf_size);
void* ptr = hglob.ToPointer();
void** ptr2 = &ptr;
size = Native.i2d_RSAPublicKey(Rsa.Handle, (byte**)ptr2);
if(size > buf_size)
throw new IndexOutOfRangeException("DER was too large!");
der = new byte[size];
Marshal.Copy(hglob,der,0,size);
Marshal.FreeHGlobal(hglob);
}
return der;
}
}
编辑 - Woot : 看起来 RSAWrapper class 非常具有凝聚力和模块化。 我能够将它复制出来——它只需要访问 OpenSSL 库,它还有一个 RSA.FromPublicKey(string s);创建 RSA 的方法。
所以现在,我可以做到
RSAWrapper rsaWrapper = new RSAWrapper("d:\pubkey.txt", true);
Console.WriteLine(rsaWrapper.OnionHash);
花了几个月的时间 - 但得到了比我打算得到的更好的答案。 现在我可以使用 public 键,并验证洋葱地址是否与 public 键匹配。这将验证洋葱地址的所有权,而无需通过网络发送私钥的风险。