FYI, this is the format used by vanitygen 0.22 when you specify -e.
I had a hell of a time sorting out how to decode them, thought this might help someone else. I'm using PHP, but PHP is easy to read. I'm using
an external PBKDF2 function. If you use the function included with newer PHP versions, you may need to adjust the parameter order. The mcrypt_cbc() is old too, check with the PHP manual for updated information, or use
phpseclib.
The $input value is the raw base58coded string. My base58decode function returns the binary output without verifying the check value. If yours checks it before returning, you can skip that part.
The output value is either -1 (bad 58 check code), -2 (wrong password), or the private key as a raw binary string.
function keydecrypt($input,$password){
$data=base58decode($input);
$style=substr($data,0,1);
$params=substr($data,1,1);
$ciphertext=substr($data,2,32);
$pwcheck=substr($data,2+32,8);
$salt=substr($data,2+32+8,4);
$code58=substr($data,2+32+8+4,4);
$check58=substr(hash("sha256",hash("sha256",$style.$params.$ciphertext.$pwcheck.$salt,TRUE),TRUE),0,4);
if($code58!=$check58)return -1; // Invalid 58 check code
$key=pbkdf2("sha256",$password,$salt,4096,64,TRUE); // 4096 is iterations, 64 is output length
$cipherkey=substr($key,0,32);
$iv=substr($key,32,16);
$hmac_key=substr($key,48,16);
$unprot=mcrypt_cbc(MCRYPT_RIJNDAEL_128,$cipherkey,$ciphertext,MCRYPT_DECRYPT,$iv);
$hmac=substr(hash_hmac("sha256",$unprot,$hmac_key,TURE),0,8);
if($hmac!=$pwcheck)return -2; // Invalid password
return $unprot;
}
?>
If using phpseclib, use this instead of the mcrypt_cbc call:
require_once("Crypt/AES.php");
$cipher = new Crypt_AES(CRYPT_AES_MODE_CBC);
$cipher->setKey($cipherkey);
$cipher->setIV($iv);
$unprot=$cipher->decrypt($cb);
?>