/ share / rpcauth / rpcauth.py
rpcauth.py
 1  #!/usr/bin/env python3
 2  # Copyright (c) 2015-2021 The Bitcoin Core developers
 3  # Distributed under the MIT software license, see the accompanying
 4  # file COPYING or http://www.opensource.org/licenses/mit-license.php.
 5  
 6  from argparse import ArgumentParser
 7  from getpass import getpass
 8  from secrets import token_hex, token_urlsafe
 9  import hmac
10  import json
11  
12  def generate_salt(size):
13      """Create size byte hex salt"""
14      return token_hex(size)
15  
16  def generate_password():
17      """Create 32 byte b64 password"""
18      return token_urlsafe(32)
19  
20  def password_to_hmac(salt, password):
21      m = hmac.new(salt.encode('utf-8'), password.encode('utf-8'), 'SHA256')
22      return m.hexdigest()
23  
24  def main():
25      parser = ArgumentParser(description='Create login credentials for a JSON-RPC user')
26      parser.add_argument('username', help='the username for authentication')
27      parser.add_argument('password', help='leave empty to generate a random password or specify "-" to prompt for password', nargs='?')
28      parser.add_argument("-j", "--json", help="output to json instead of plain-text", action='store_true')
29      args = parser.parse_args()
30  
31      if not args.password:
32          args.password = generate_password()
33      elif args.password == '-':
34          args.password = getpass()
35  
36      # Create 16 byte hex salt
37      salt = generate_salt(16)
38      password_hmac = password_to_hmac(salt, args.password)
39  
40      if args.json:
41          odict={'username':args.username, 'password':args.password, 'rpcauth':f'{args.username}:{salt}${password_hmac}'}
42          print(json.dumps(odict))
43      else:
44          print('String to be appended to bitcoin.conf:')
45          print(f'rpcauth={args.username}:{salt}${password_hmac}')
46          print(f'Your password:\n{args.password}')
47  
48  if __name__ == '__main__':
49      main()