Получить открытый ключ любой учетной записи ethereum

Могу ли я каким-то образом получить открытый ключ учетной записи ethereum, зная только соответствующий адрес эфира (например, 0x54dbb737eac5007103e729e9ab7ce64a6850a310)?

21 голос | спросил Edward Ruchevits 31 MarpmFri, 31 Mar 2017 14:34:06 +03002017-03-31T14:34:06+03:0002 2017, 14:34:06

2 ответа


21

Вы можете, если и только если транзакция была отправлена ​​из учетной записи. Когда вы отправляете tx, вы подписываете транзакцию и включаете эти значения v r и s. Вы разбираете их из подписанного tx, а затем передаете эти значения v r и s, а хеш транзакции возвращается в функцию, выплюнет открытый ключ. Это на самом деле то, как вы получаете от адреса транзакции.

  

Вы можете сделать это самостоятельно, используя инструмент, например ethereumjs -utils :

/**
 * ECDSA public key recovery from signature
 * @param {Buffer} msgHash
 * @param {Number} v
 * @param {Buffer} r
 * @param {Buffer} s
 * @return {Buffer} publicKey
 */
exports.ecrecover = function (msgHash, v, r, s) {
  var signature = Buffer.concat([exports.setLength(r, 32), exports.setLength(s, 32)], 64)
  var recovery = v - 27
  if (recovery !== 0 && recovery !== 1) {
    throw new Error('Invalid signature v value')
  }
  var senderPubKey = secp256k1.recover(msgHash, signature, recovery)
  return secp256k1.publicKeyConvert(senderPubKey, false).slice(1)
}

  

Как другой реальный сценарий, ethereumjs-tx использует эту функцию для проверки подписи:

/**
* Determines if the signature is valid
* @return {Boolean}
*/
verifySignature () {
  const msgHash = this.hash(false)
  // All transaction signatures whose s-value is greater than secp256k1n/2 are considered invalid.
  if (this._homestead && new BN(this.s).cmp(N_DIV_2) === 1) {
    return false
  }

  try {
    let v = ethUtil.bufferToInt(this.v)
    if (this._chainId > 0) {
      v -= this._chainId * 2 + 8
    }
    this._senderPubKey = ethUtil.ecrecover(msgHash, v, this.r, this.s)
  } catch (e) {
    return false
  }

  return !!this._senderPubKey
}

Для получения дополнительной информации о v r и s:

  

v, r и s - параметры, которые можно проанализировать из сигнатуры. Вот хороший пример из библиотеки uthereumjs utils:

 var sig = secp256k1.sign(msgHash, privateKey)
  var ret = {}
  ret.r = sig.signature.slice(0, 32)
  ret.s = sig.signature.slice(32, 64)
  ret.v = sig.recovery + 27
  

Обратите внимание, как вы можете анализировать каждое значение из заданной сигнатуры.

источник

ответил tayvano 4 AMpTue, 04 Apr 2017 07:54:57 +030054Tuesday 2017, 07:54:57
6

Я не думаю, что это возможно, поскольку вы теряете информацию при переходе от открытого ключа к адресу:

  
  1. Начать с открытого ключа (64 байта)
  2.   
  3. Возьмите хэш Keccak-256 открытого ключа. Теперь у вас должна быть строка размером 32 байта. (примечание: SHA3-256 в конечном итоге стал стандартом, но Ethereum использует Keccak)
  4.   
  5. Возьмите последние 20 байтов этого открытого ключа (Keccak-256). Или, другими словами, удалить первые 12 байтов . Эти 20 байтов являются адресом или 40 символами. При префиксе 0x он составляет 42 символа.
  6.   

Как генерируются эфирские адреса?

ответил Olmo Ziarko 31 MarpmFri, 31 Mar 2017 14:40:47 +03002017-03-31T14:40:47+03:0002 2017, 14:40:47

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132