cara membuat bitcoin address dengan java script indonesia


Berikut adalah terjemahan dari website ini :
http://perstarwaw.blogspot.co.id/2016/07/membuat-bitcoin-address-dengan-java-script.html



Menghasilkan Alamat Bitcoin dengan JavaScript
Jika Anda tidak terbiasa dengan Bitcoin, Bitcoin pada dasarnya adalah sebuah mata uang P2P yang telah meningkat urutan besarnya nilai dalam tahun lalu. Video ini melakukan pekerjaan yang baik menjelaskan itu. Ada sejumlah perpustakaan untuk bekerja dengan Bitcoin dalam beberapa bahasa yang paling populer: C, Java, C #, Ruby, Python, Go, dan JavaScript. Artikel ini akan fokus secara eksklusif pada perpustakaan JavaScript.

Disclaimer: Saya tidak ahli kriptografi dan saran kriptografi tersebut atau implementasi harus diterima sebagai eksperimen akademik dan tidak kripto praktik terbaik.

Random Number Generation
Saya akan lalai jika saya tidak menyebutkan apa-apa tentang generasi nomor acak. Generasi nomor acak adalah dasar dari yang paling kriptografi dan Bitcoin. alamat Bitcoin Anda hanya aman seperti nomor acak generator Anda. Sejumlah acak generator yang dikatakan kriptografi aman jika cukup baik untuk digunakan untuk kriptografi dalam bahwa ada cukup entropi bagi seseorang untuk memprediksi generator nomor. Math.random () tidak cryptographically aman. Hal ini karena Math.random () diprediksi. Jika itu diprediksi, penyerang bisa mengetahui kunci privat dari kunci publik Anda. Implikasi dari orang lain mengetahui kunci pribadi Anda berarti bahwa mereka juga bisa menghabiskan Bitcoins Anda.

Pada saat penulisan ini, dominan perpustakaan JavaScript Bitcoin menggunakan CryptoJS yang mengejutkan menggunakan Math.random (). Artikel ini menunjukkan bagaimana Anda dapat menggunakan dan datang window.crytpo standar atau Stanford JavaScript Crypto Library

Bacaan lebih lanjut:

Anatomi generator nomor pseudorandom - Visualisasi Cryptocat ini kereta PRNG
tes apa yang bisa saya lakukan untuk memastikan PRNG saya bekerja dengan benar?
Handbook of Applied Cryptography - Bab 5: Pseudorandom Bits dan Urutan
Bitcoin Bicara: Android Key Rotasi
Bitcoin Bicara: Signatures Bad mengarah ke 55,82 pencurian BTC
Android Developer: Beberapa SecureRandom Pikiran
Semua Bitcoin Android diciptakan dompet rentan terhadap pencurian
Google menegaskan kritis cacat kripto Android digunakan di $ 5.700 Bitcoin pencurian
Acak gagal! Kelemahan di Jawa Pseudo Random Number Generator
window.crypto.getRandomValues ()
Mulai
Anda akan ingin menggunakan terbaru BitcoinJS klien lib. Ini cukup usang sekalipun. Ada beberapa garpu lebih baru: 1, 2, dan salah satu yang saya akhirnya akan mempertahankan. Untuk saat ini, gunakan salah satu usang, dari BitcoinJS.

Saya telah menyertakan perpustakaan di halaman ini. Hanya membuka Konsol Chrome atau Firefox Console dan mulai mengetik di sepanjang.

Bitcoin Keys, Alamat, & Format
Bitcoin berasal keamanan dari skema kripto kunci publik Elliptic Curve Cryptography (ECC). Jadi, mengapa desainer dari Bitcoin, Satoshi Nakamoto, memutuskan untuk menggunakan ECC lebih skema kripto RSA lazim? Manfaat utama adalah ukuran kunci. Menurut artikel Wikipedia pada ECC, "256-bit ECC kunci publik harus memberikan keamanan sebanding dengan 3072-bit RSA public key".

Elliptical Curve Cryptography spesifikasi 2.2.1 menyatakan bahwa kriptografi yang diatur oleh persamaan:

y2 = (x3 + ax + b) MODP
y2 = (x3 + ax + b) MODP
Seluruh domain kurva eliptik adalah sextuple, spesifikasi 3.1.1:

T = (p, a, b, G, n, h)
T = (p, a, b, G, n, h)
Rincian yang tepat berada di luar ruang lingkup untuk artikel ini, baca spec untuk info lebih lanjut. Bitcoin menggunakan secp256k1 (info di 2.7.1) pelaksanaan, yang menggunakan kurva Koblitz.

Parameter sextuple untuk secpk256k1 adalah:

p: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F
a: 0
b: 7
G (terkompresi): 02 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798
G (terkompresi): 04 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798 483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8
n: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141
h: 1
sehingga mengurangi persamaan kurva elips untuk:

y2 = (x3 + 7) MODP
y2 = (x3 + 7) MODP
Anda benar-benar tidak perlu memahami banyak ini. Aku terutama disajikan materi ini untuk tujuan akademik.

Keys pribadi
kunci pribadi adalah apa yang memungkinkan Anda untuk menghabiskan uang Anda. Kunci privat, d adalah setiap angka acak antara 1 dan n - 1. Menurut spec (3.2.1): "kurva eliptik sepasang kunci (d, Q) yang terkait dengan T terdiri dari kurva eliptik kunci rahasia d yang integer dalam interval [1, n - 1], dan kurva eliptik kunci publik Q = (xQ, YQ) Q = (xQ, YQ) yang merupakan titik Q = dGQ = dG.

Anda akan melihat bahwa kita menghasilkan 32 nilai acak. Dan n tidak memiliki maksimal 2256-12256-1, sehingga secara teoritis mungkin untuk menghasilkan kunci lebih besar dari perintah standar. Namun, dalam prakteknya, Anda benar-benar tidak perlu khawatir tentang hal itu.

mari kita menghasilkan kunci pribadi:

var randArr = baru Uint8Array (32) // membuat array diketik dari 32 byte (256 bit)
window.crypto.getRandomValues (randArr) // mengisi array dengan nomor acak cryptographically aman

// Beberapa metode Bitcoin dan Crypto tidak suka Uint8Array untuk input. Mereka mengharapkan array JS biasa.
var privateKeyBytes = []
for (var i = 0; i <randArr.length; ++ i)
  privateKeyBytes [i] = randArr [i]

// Jika Anda ingin mengikuti hasil langkah-demi-langkah dalam artikel ini, komentar para
// Kode sebelumnya dan tanda komentar berikut
// Var privateKeyBytes = Crypto.util.hexToBytes ( "1184CD2CDD640CA42CFC3A091C51D549B2F016D454B2774019C2B2D2E08529FD")

// Hex string kunci pribadi kita
var privateKeyHex = Crypto.util.bytesToHex (privateKeyBytes) .toUpperCase ()
console.log (privateKeyHex) // 1184CD2CDD640CA42CFC3A091C51D549B2F016D454B2774019C2B2D2E08529FD
cukup sederhana, ya? Tapi tunggu, ini tidak terlihat seperti kunci pribadi yang Anda lihat dalam klien Bitcoin Anda. Jadi apa yang terjadi? kunci pribadi biasanya menggunakan format yang disebut Wallet Impor Format (WIF).

Format Impor dompet

Dompet Import Format (WIF) adalah cara yang lebih pendek untuk menyandikan kunci pribadi. Ini adalah dasar 58 encoding dari 0x80 + kunci pribadi + checksum.

menghasilkan WIF di JS:

// Menambahkan 0x80 ke depan, https://en.bitcoin.it/wiki/List_of_address_prefixes
var privateKeyAndVersion = "80" + privateKeyHex
var firstSHA = Crypto.SHA256 (Crypto.util.hexToBytes (privateKeyAndVersion))
var secondSHA = Crypto.SHA256 (Crypto.util.hexToBytes (firstSHA))
var checksum = secondSHA.substr (0, 8) .toUpperCase ()
console.log (checksum) // "206EC97E"

// Menambahkan checksum untuk mengakhiri kunci pribadi dan versi
var keyWithChecksum = privateKeyAndVersion + checksum
console.log (keyWithChecksum) // "801184CD2CDD640CA42CFC3A091C51D549B2F016D454B2774019C2B2D2E08529FD206EC97E"

var privateKeyWIF = Bitcoin.Base58.encode (Crypto.util.hexToBytes (keyWithChecksum))
console.log (privateKeyWIF) // "5Hx15HFGyep2CfPxsJKe2fXJsCVn5DEiyoeGGF6JZjGbTRnqfiD"
Anda dapat memverifikasi bahwa ini memeriksa keluar dengan melihat baik di http://brainwallet.org dan memasukkan nilai privateKeyHex untuk input ke Secret Eksponen. Anda juga dapat memverifikasi http://gobittest.appspot.com/PrivateKey.

Namun, ada metode yang jauh lebih mudah digunakan:

// Ingat, "privateKeyBytes" adalah array dari angka acak
var privateKeyWIF = baru Bitcoin.Address (privateKeyBytes)
privateKeyWIF.version = 0x80 // 0x80 = 128, https://en.bitcoin.it/wiki/List_of_address_prefixes
privateKeyWIF = privateKeyWIF.toString ()
console.log (privateKeyWIF) // "5Hx15HFGyep2CfPxsJKe2fXJsCVn5DEiyoeGGF6JZjGbTRnqfiD"
Kunci publik
Sekarang kita memiliki kunci pribadi kita, kita dapat menghasilkan kunci publik. Ingat bahwa kunci Bitcoin menggunakan secp256k1 (info di 2.7.1) parameter. kunci publik yang dihasilkan oleh:

Q = dG
Q = dG
mana QQ adalah kunci publik, dd adalah kunci pribadi, dan GG adalah parameter kurva. Kunci publik adalah nilai panjang 65 byte terdiri dari 0x04 terkemuka dan X dan Y koordinat 32 byte masing-masing.

kurva var = getSECCurveByName ( "secp256k1") // ditemukan di bitcoinjs-lib / src / jsbn / sec.js

// Mengkonversi acak array kami atau kunci pribadi ke Big Integer
var privateKeyBN = BigInteger.fromByteArrayUnsigned (input)

var curvePt = curve.getG (). kalikan (privateKeyBN)
var x = curvePt.getX (). toBigInteger ()
var y = curvePt.getY (). toBigInteger ()
var publicKeyBytes = integerToBytes (x, 32) // integerToBytes ditemukan di bitcoinjs-lib / src / ecdsa.js
publicKeyBytes = publicKeyBytes.concat (integerToBytes (y, 32))
publicKeyBytes.unshift (0x04)
var publicKeyHex = Crypto.util.bytesToHex (publicKeyBytes)

console.log (publicKeyHex)
/ * Output:
04d0988bfa799f7d7ef9ab3de97ef481cd0f75d2367ad456607647edde665d6f6
fbdd594388756a7beaf73b4822bc22d36e9bda7db82df2b8b623673eefc0b7495
* /
output ini dapat diverifikasi dengan http://brainwallet.org.

Compressed Keys

Anda mungkin pernah mendengar tentang kunci Compressed. Jawaban yang sangat baik di Bitcoin Stack Efek menjelaskan perbedaan:

Kunci dikompresi adalah cara menyimpan kunci publik dalam byte lebih sedikit (33 bukan 65). Tidak ada kompatibilitas atau masalah keamanan karena mereka justru kunci yang sama, hanya disimpan dengan cara yang berbeda. Perangkat lunak Bitcoin asli tidak menggunakan kunci terkompresi hanya karena penggunaannya buruk didokumentasikan dalam OpenSSL. Mereka tidak memiliki kelemahan selain itu sedikit perhitungan tambahan yang diperlukan sebelum mereka dapat digunakan untuk memvalidasi tanda tangan.

Jika Anda berpikir dari kunci publik sebagai titik di suatu tempat di sepanjang U raksasa, kunci terkompresi adalah X dan Y koordinat titik. Kunci dikompresi adalah bagaimana tinggi di U intinya adalah bersama dengan satu bit yang menunjukkan apakah itu di sisi kiri atau kanan. Seperti yang dapat Anda bayangkan, mereka berdua menyandikan justru hal yang sama, tetapi bentuk terkompresi membutuhkan setengah banyak ruang ditambah satu bit. (Tentu saja, mereka benar-benar menunjukkan pada elliptic curve secp256k1, tapi konsep yang sama.)

- David Schwartz
Ada sedikit alasan untuk menggunakan kunci terkompresi. Mari kita menghasilkan kunci publik terkompresi:

var publicKeyBytesCompressed = integerToBytes (x, 32) // x dari atas
jika (y.isEven ())
  publicKeyBytesCompressed.unshift (0x02)
lain
  publicKeyBytesCompressed.unshift (0x03)

var publicKeyHexCompressed = Crypto.util.bytesToHex (publicKeyBytesCompressed)
console.log (publicKeyHexCompressed)
/ * Output:
03d0988bfa799f7d7ef9ab3de97ef481cd0f75d2367ad456607647edde665d6f6f
* /
Anda dapat melihat bahwa ini cocok hingga http://brainwallet.org ketika Compressed diklik.

Ini mungkin untuk melakukan semua ini dalam banyak langkah yang lebih pendek:

// PrivateKeyBytes adalah array kunci pribadi dari atas
var eckey = Bitcoin.ECKey baru (privateKeyBytes)
var publicKeyHex = Crypto.util.bytesToHex (eckey.getPub ())
console.log (publicKeyHex)
/ * Output:
04d0988bfa799f7d7ef9ab3de97ef481cd0f75d2367ad456607647edde665d6f6
fbdd594388756a7beaf73b4822bc22d36e9bda7db82df2b8b623673eefc0b7495
* /

eckey.compressed = true
var publicKeyHexCompressed = Crypto.util.bytesToHex (eckey.getPub ())
Keys Swasta Compressed

Anda mungkin telah memperhatikan bahwa ketika Anda beralih bolak-balik antara Compressed dan terkompresi pada http://brainwallet.org bahwa perubahan Key Swasta juga. Jadi, jika Anda mengimpor kunci pribadi ke dalam dompet Anda, yang kunci publik itu akan digunakan? jawaban lain baik di Bitcoin Stack Exchange pada bagaimana untuk menangani hal ini:

... Dengan demikian, dalam rangka untuk mendukung kedua, kita harus ingat untuk setiap / keypair public private apakah encoding normal atau dikompresi akan digunakan. Saat Anda menunjukkan, kami juga membutuhkan informasi ini ketika mengimpor kunci pribadi. Untuk melakukannya, "Dompet Impor Format" untuk kunci privat (bentuk base58, biasanya dimulai dengan '5'), diperpanjang. Jika kunci / alamat publik untuk kunci pribadi tertentu yang harus berasal dari pengkodean terkompresi dari kunci publik, kunci pribadi mendapat 0x01 byte tambahan di akhir, sehingga bentuk base58 yang dimulai dengan 'K' atau 'L '.

Jadi untuk menjawab pertanyaan Anda: ketika mengimpor kunci pribadi ke klien referensi, ia akan menggunakan pengkodean normal untuk kunci publik jika '5' Format digunakan untuk kunci pribadi, dan encoding dikompresi jika 'K' / 'L 'Format digunakan. Ini tidak masuk akal untuk mencoba untuk mengkonversi satu ke yang lain: klien harus menggunakan pengkodean yang sama seperti yang digunakan saat membuat alamat, atau alamat tidak akan cocok. Sayangnya, cukup banyak software tidak mendukung kunci publik terkompresi belum (yang sangat disayangkan, karena mereka menghemat ruang rantai blok).

- Pieter Wuille
mari kita menghasilkan kunci terkompresi pribadi kita:

var privateKeyBytesCompressed = privateKeyBytes.slice (0) // clone Array
privateKeyBytesCompressed.push (0x01)
var privateKeyWIFCompressed = baru Bitcoin.Address (privateKeyBytesCompressed)
privateKeyWIFCompressed.version = 0x80
privateKeyWIFCompressed = privateKeyWIFCompressed.toString ()

console.log (privateKeyWIFCompressed) // KwomKti1X3tYJUUMb1TGSM2mrZk1wb1aHisUNHCQXTZq5auC2qc3
Sekali lagi, memverifikasi cocok http://brainwallet.org.

Alamat
Bitcoin menggunakan alamat sebagai sarana untuk menerima koin dari orang lain. Alamat adalah string base58 encoded dari alamat biner 25 byte. Semua alamat Bitcoin mulai dengan 1. Seseorang dapat memiliki alamat yang mereka inginkan. Menggunakan lebih dari satu alamat dikatakan meningkat anonimitas. kunci pribadi memberikan Anda akses untuk menghabiskan uang yang terkait dengan alamat.

Alamat yang dihasilkan seperti berikut:

Versi = 1 byte 0 (nol); pada jaringan tes, ini adalah 1 byte dari 111

Key hash = Versi digabungkan dengan RIPEMD-160 (SHA-256 (kunci publik))

Checksum = 1 4 byte SHA-256 (SHA-256 (hash Key))

Bitcoin Alamat = Base58Encode (hash Key digabungkan dengan Checksum)

- Bitcoin Wiki: Alamat
Dikompresi, dikompresi, zomg ... ya, ada dua alamat yang terkait dengan setiap ECC kunci pribadi. Prosedur ini persis sama:

// Bisa menggunakan publicKeyBytesCompressed juga
var hash160 = Crypto.RIPEMD160 (Crypto.util.hexToBytes (Crypto.SHA256 (publicKeyBytes)))
console.log (hash160) // "3c176e659bea0f29a3e9bf7880c112b1b31b4dc8"

Versi var = 0x00 // jika menggunakan testnet, akan menggunakan 0x6F atau 111.
var hashAndBytes = Crypto.util.hexToBytes (hash160)
hashAndBytes.unshift (versi)

var doubleSHA = Crypto.SHA256 (Crypto.util.hexToBytes (Crypto.SHA256 (hashAndBytes)))
var addressChecksum = doubleSHA.substr (0,8)
console.log (addressChecksum) // 26268187

var unencodedAddress = "00" + hash160 + addressChecksum

console.log (unencodedAddress)
/ * Output
  003c176e659bea0f29a3e9bf7880c112b1b31b4dc826268187
* /

alamat var = Bitcoin.Base58.encode (Crypto.util.hexToBytes (unencodedAddress))
console.log (alamat) // 16UjcYNBG9GTK4uq2f7yYEbuifqCzoLMGS
lebih mudah ...

alamat var = Bitcoin.Address baru (Crypto.util.hexToBytes (hash160))
address.version = 0x00 // testnet akan 0x6F
address = address.toString ()
ok, yang paling mudah dari semua ...

alamat var = eckey.getBicoinAddress (). toString () // "eckey" dari atas
console.log (alamat) //// 16UjcYNBG9GTK4uq2f7yYEbuifqCzoLMGS

// Anda harus membuat yang baru jika Anda sudah disebut getBitcoinAddress () untuk
// Alamat mewakili versi terkompresi
var eckey2 = Bitcoin.ECKey baru (privateKeyBytes)
eckey2.compressed = true
var addressForCompressed = eckey2.getBitcoinAddress (). toString ()
console.log (addressForCompressed) // 1FkKMsKNJqWSDvTvETqcCeHcUQQ64kSC6s
ganda Hashing
OK, Anda mungkin melihat banyak. Sekali lagi, aku akan menunda untuk Internets dan peeps pintar dari saya:

Dari: Mengapa Bitcoin menggunakan dua fungsi hash (SHA-256 dan RIPEMD-160) untuk membuat alamat?

RIPEMD digunakan karena menghasilkan hash terpendek yang keunikannya masih cukup terjamin. Hal ini memungkinkan Bitcoin membahas lebih pendek.

SHA256 digunakan juga karena penggunaan Bitcoin untuk hash dari kunci publik dapat membuat kelemahan yang unik karena interaksi tak terduga antara RIPEMD dan ECDSA (algoritma tanda kunci publik). Interposing operasi hash tambahan dan sangat berbeda antara RIPEMD dan ECDSA membuatnya hampir tak terbayangkan bahwa mungkin ada cara untuk menemukan tabrakan alamat yang secara signifikan lebih mudah daripada brute force mencoba sejumlah besar kunci rahasia.

Pada dasarnya, itu adalah sabuk dan suspender pendekatan. Bitcoin harus melakukan sesuatu yang unik dan daripada harus berharap mereka mendapatkannya tepat, mereka dirancang terlalu berlebihan itu.

- David Schwartz
dan SHA256 yang (SHA256 (input)):

Jadi mengapa ia hash dua kali? Saya menduga itu untuk mencegah serangan panjang-ekstensi.

SHA-2, seperti semua hash Merkle-Damgard menderita properti yang disebut "panjang-ekstensi". Hal ini memungkinkan penyerang yang tahu H (x) untuk menghitung H (x || y) tanpa mengetahui x. Hal ini biasanya tidak masalah, tetapi ada beberapa penggunaan di mana itu benar-benar istirahat keamanan. Contoh yang paling relevan adalah menggunakan H (k || m) sebagai MAC, di mana seorang penyerang dapat dengan mudah menghitung MAC untuk m || m '. Saya tidak berpikir Bitcoin pernah menggunakan hash dengan cara yang akan menderita ekstensi panjang, tapi saya kira Satoshi pergi dengan pilihan yang aman untuk mencegah hal itu di mana-mana.

Untuk menghindari properti ini, Ferguson dan Schneier menyarankan menggunakan SHA256d = SHA256 (SHA256 (x)) yang menghindari serangan panjang-ekstensi. Konstruksi ini memiliki beberapa kelemahan minor (tidak relevan dengan Bitcoin), jadi saya tidak akan merekomendasikan untuk protokol baru, dan akan menggunakan HMAC dengan kunci konstan, atau dipotong SHA512 gantinya.

Dijawab oleh CodesInChaos
Ringkasan
kunci Compressed adalah format yang lebih disukai sekarang. Mari kita lakukan ini dalam satu potongan JS cepat untuk membuat semuanya bodoh sederhana dan kompatibel dengan hampir setiap klien Bitcoin:

var randArr = baru Uint8Array (32) // membuat array diketik dari 32 byte (256 bit)
window.crypto.getRandomValues (randArr) // mengisi array dengan nomor acak cryptographically aman

// Beberapa metode Bitcoin dan Crypto tidak suka Uint8Array untuk input. Mereka mengharapkan array JS biasa.
var privateKeyBytes = []
for (var i = 0; i <randArr.length; ++ i)
  privateKeyBytes [i] = randArr [i]

var eckey = Bitcoin.ECKey baru (privateKeyBytes)
eckey.compressed = true
alamat var = eckey.getBitcoinAddress (). toString ()
console.log (alamat) // 1FkKMsKNJqWSDvTvETqcCeHcUQQ64kSC6s


var privateKeyBytesCompressed = privateKeyBytes.slice (0) // clone Array
privateKeyBytesCompressed.push (0x01)
var privateKeyWIFCompressed = baru Bitcoin.Address (privateKeyBytesCompressed)
privateKeyWIFCompressed.version = 0x80
privateKeyWIFCompressed = privateKeyWIFCompressed.toString ()

console.log (privateKeyWIFCompressed) // KwomKti1X3tYJUUMb1TGSM2mrZk1wb1aHisUNHCQXTZq5auC2qc3
Di sana Anda memilikinya! KwomKti1X3tYJUUMb1TGSM2mrZk1wb1aHisUNHCQXTZq5auC2qc3 adalah kunci pribadi Anda dalam bentuk WIF yang memungkinkan Anda untuk mengirim uang untuk 1FkKMsKNJqWSDvTvETqcCeHcUQQ64kSC6s alamat.

Alamat dan Keys dari Password atau Passphrase

Anda dapat menghasilkan kunci pribadi dari passphrase. Salah satu metode akan hanya menghitung hash SHA256 ganda pada pengguna passphrase dan menggunakannya sebagai kunci pribadi.

sandi var = "hanya ada satu"
var privateKeyHex = Crytpo.util.SHA256 (Crypto.util.hexToBytes (Crypto.util.SHA256 (password)))
var privateKeyBytes = Crypto.util.hexToBytes (privateKeyHex)
Previous
Next Post »
Post a Comment
Thanks for your comment