简体   繁体   中英

How to generate Terra's private key like the one Terra Station Wallet produces?

Does anyone know how the Terra Station Wallet generates the 364 characters Private Key? I am looking for a way to generate this 364 characters Private Key using terra-sdk, but the length of the mk = MnemonicKey() 's mk.private_key is not 364 characters.

Appreciate any help

You sparked my curiosity. I went through the Terra Station code (I chose mobile) to see how they do it. I first searched for where in the UI was the “Export Private Key”; it looks to be the encrypted Key string in AuthDataValueType.

Here's where they read it out of keystore. https://github.com/terra-money/station-mobile/blob/f74c4224986fd9ed32b4380b537e9ae13ca05c3e/src/utils/authData.ts#L15

Here's where they create it for a newly recovered wallet. https://github.com/terra-money/station-mobile/blob/3ec15b9a620432dee47378f5b6e621d93780748a/src/utils/wallet.ts#L66

And, lastly here are the encrypt util functions. https://github.com/terra-money/station-mobile/blob/3ec15b9a620432dee47378f5b6e621d93780748a/src/utils/crypto.ts

This is all NodeJS/ReactNative code so you would need to create the same encrypt/decrypt, password and storage flow in Python, if necessary.

The import 'key' for Terra Station is actually a base64 encoded JSON object containing the wallet name, Terra address and the private key (which is further AES encrypted and base64 encoded). This is some C# to create it (you will need to get the private key using something like the Mnemonic Code Converter webpage) - fill in the string variables at the top:

        string privatekey = @"";  
        string walletName = @"";
        string address = @"";
        string password = @"changeme";

        byte[] salt = Encoding.UTF8.GetBytes("kopwemdmondawfwa");
        byte[] iv = Encoding.UTF8.GetBytes("dgfdkfsokwedopmf");
        int iterations = 100;
        int keySize = 256;

        var myRijndael = new RijndaelManaged();

        myRijndael.KeySize = keySize; 
        myRijndael.IV = iv;

        var rfc2898 = new Rfc2898DeriveBytes(System.Text.Encoding.UTF8.GetBytes(password), salt, iterations);
        byte[] key = rfc2898.GetBytes(keySize / 8);

        myRijndael.Key = key;
        myRijndael.Padding = PaddingMode.PKCS7;
        myRijndael.Mode = CipherMode.CBC;
        ICryptoTransform transform = myRijndael.CreateEncryptor();

        byte[] bak = new System.Text.UTF8Encoding().GetBytes(privatekey);
        byte[] encrypted = transform.TransformFinalBlock(bak, 0, bak.Length);

        string saltStr = BitConverter.ToString(salt).Replace("-", ""); 
        string ivStr = BitConverter.ToString(iv).Replace("-", "");  
        string cipherStr = System.Convert.ToBase64String(encrypted);

        string keyString = saltStr + ivStr + cipherStr;

        string res = "{ \"name\":\"" + walletName + "\",\"address\":\"" + address + "\",\"encrypted_key\":\"" + keyString + "\"}";
        byte[] resBytes = new System.Text.UTF8Encoding().GetBytes(res);
        string base64 = System.Convert.ToBase64String(resBytes);

        File.WriteAllText(@"c:\temp\ts_exported_key.txt", base64);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM