所以我试图用C#生成比特币密钥对(想想脑钱包)。我在Warp Wallet生成相同的密钥对时获得了有效的公钥,但生成的私钥与Warp Wallet不同,如果我尝试在某些网站上测试它,它也无效。
我如何获得错误的私钥但是正确的相应公钥?
我正在使用KeyCore来生成密钥对。
我用来生成代码的C#代码如下:
class Program {
const string salt = "a@b.c";
static void Main(string[] args) {
GetKeyPair("Password");
Console.ReadLine();
}
private static byte[] GetScrypt(string passphrase) {
//scrypt(key=(passphrase||0x1), salt=(salt||0x1), N=2^18, r=8, p=1, dkLen=32)
//Setup Lists to take the extra byte of the byte array to the end
var passArrList = new List<byte>();
var saltArrList = new List<byte>();
//Get the byte array of incoming passphrase
byte[] passArr = Encoding.UTF8.GetBytes(passphrase);
//Add the pass byte array to the list
passArrList.AddRange(passArr);
//Append the needed 0x1 to the end of the array
passArrList.Add(1);
//Get the bytes of the salt
byte[] saltArr = Encoding.UTF8.GetBytes(salt);
//Add the salt to the list
saltArrList.AddRange(saltArr);
//Append the needed salt to the end
saltArrList.Add(1);
//Byte array to store scrypt bytes
byte[] scryptBytes = CryptSharp.Utility.SCrypt.ComputeDerivedKey(passArrList.ToArray(), saltArrList.ToArray(), 262144, 8, 1, null, 32);
//Return SHA256 byte array
return scryptBytes;
}
private static byte[] GetPBKDF2(string passphrase) {
//pbkdf2(key=(passphrase||0x2), salt=(salt||0x2), c=216, dkLen=32, prf=HMAC_SHA256)
//Setup Lists to take the extra byte of the byte array to the end
var passArrList = new List<byte>();
var saltArrList = new List<byte>();
//Get the byte array of incoming passphrase
byte[] passArr = Encoding.UTF8.GetBytes(passphrase);
//Add the pass byte array to the list
passArrList.AddRange(passArr);
//Append the needed 0x1 to the end of the array
passArrList.Add(2);
//Get the bytes of the salt
byte[] saltArr = Encoding.UTF8.GetBytes(salt);
//Add the salt to the list
saltArrList.AddRange(saltArr);
//Append the needed salt to the end
saltArrList.Add(2);
//Setup the hashing algorithm
var hashAlgo = new HMACSHA256(passArrList.ToArray());
//Byte array for PBKDF2
byte[] pbkdf2Bytes = CryptSharp.Utility.Pbkdf2.ComputeDerivedKey(hashAlgo, saltArrList.ToArray(), 65536, 32);
return pbkdf2Bytes;
}
private static void GetKeyPair(string passphrase) {
byte[] scrypt = GetScrypt(passphrase);
byte[] PBKDF2 = GetPBKDF2(passphrase);
byte[] resultBuffer = new byte[scrypt.Length];
for (int i = 0; i < PBKDF2.Length; i++) {
resultBuffer[i] = (byte)(scrypt[i] ^ PBKDF2[i]);
}
byte[] sha256 = new SHA256Managed().ComputeHash(resultBuffer);
//create a private key using seedBytes which forces the public key to be compressed and supplying compressedPublicKey as false so the public key will not be compressed
PrivateKey pkNotCompressed = new PrivateKey(Globals.ProdAddressVersion, resultBuffer, false);
//get the wif encoded string that represents the pkNotCompressed private key
String wif = pkNotCompressed.WIFEncodedPrivateKeyString;
//here we can create a bitcoin address string using the public key ascociated with our private key
String bitcoinAddress = BitcoinAddress.GetBitcoinAdressEncodedStringFromPublicKey(pkNotCompressed.PublicKey);
Console.WriteLine($"WIF (Uncrompressed): {wif} \n");
Console.WriteLine($"Bitcoin Address (Uncrompressed): {bitcoinAddress} \n");
}
}