1

I'm looking to implement a "Verify with Bitcoin-OTC" feature for my web app. The general idea is the user would prove he owns a particular account on the external site Bitcoin-OTC and my app would accept/deny him based on his rating there.

Here's how I'm thinking of implementing this:

  1. User provides Bitcoin-OTC username.
  2. My app looks up his GPG fingerprint using this bitcoin-otc gem.
  3. My app presents the user with his encrypted one-time password and asks him to decrypt it.
  4. User provides decrypted password.
  5. My app verifies it with the gpg everify command on Freenode and accepts/denies the user.

The part I'm struggling with is step #5. I'm doing it this way because I'm not sure Bitcoin-OTC exposes an API. I'm not sure how to programmatically communicate with the bot on their IRC channel.

Steps 1-5 are basically how a user would verify himself on the Bitcoin-OTC IRC channel except my app is acting as a middleman.

My questions are:

  • How can I achieve step #5?
  • Does adding my app into this flow introduce any security risks?

Edit:

I've been doing some research and I've realized I can probably just get the user to sign a message stating he owns the Bitcoin-OTC account in question.

If the message is signed with the fingerprint tied to the Bitcoin-OTC account and the signature is trusted, then can I be sure the user is who he says he is?

Here is my proposed flow in an ad-hoc Ruby script:

require 'bitcoin/otc'

account = Bitcoin::OTC::Account['mhluska']

message = Time.now.to_i.to_s + " I am the owner of username #{account.nick} on Bitcoin-OTC"

puts 'Run the following command to sign a message using your GPG fingerprint #{account.fingerprint}:'
puts "$ echo \"#{message}\" | gpg --clearsign"
puts "Paste it back here and press Ctrl+D"

$/ = "\0"
message = STDIN.gets

response = %x[echo "#{message}" | gpg --verify 2>&1]

if response.include?('Good signature')
  if response.include?('This key is not certified')
    puts 'Good signature but untrusted'
  else
    puts 'Good signature and trusted'
  end
else
  puts 'Bad signature'
end
Maros
  • 113
  • 6
  • #5 is not a security question but a question for the Bitcoin-OTC's devs. – schroeder Feb 06 '15 at 19:03
  • Oops. Sorry. Then I hope to just get advice on the whole flow from a security standpoint. – Maros Feb 06 '15 at 19:04
  • No problem. You have an interesting scenario. – schroeder Feb 06 '15 at 19:08
  • **Important**: you need to change your code to have it check for the message you're asking be signed. At the moment, it looks like it would work with *any* signature using that key. People often put signed messages on public forums, etc. – AJAr Feb 06 '15 at 22:43

1 Answers1

1

Rather than going through the whole #bitcoin-otc login procedure on behalf of your users (which, in the case of an existing session, may either be denied or attempt to replace the current session), you could have a bot present in #bitcoin-otc and then either require the ident-verified users to message it with a randomly generated token, or have them request a token from the bot to use on the website. You could decouple the bot from your main backend as well by providing the user with an encoded message that includes the verified response from ident signed by your bot — you would not need to implement any communication between the bot and your main app components since it would just endorse responses from ident. I believe that users would feel more secure with some of these approaches, as there may be some concern about a remote agent performing this auth within a largely security-aware community.

Most languages have established IRC libs, so it should be pretty straightforward once you get familiar with one for your language of choice.

EDIT

If you just want to verify ownership of a GPG-verified account, then just roll your own GPG verification. If you prefer Ruby, you can use https://github.com/ueno/ruby-gpgme to encrypt a signed/timestamped token for the user's public key. You wouldn't have to keep state, just verify that the token provided has a valid signature applied by your server. There may already be an open implementation like this today.

AJAr
  • 1,682
  • 1
  • 9
  • 19
  • Thanks for your response. This seems like a good solution. Though I've posted an edit with a new idea involving just plain old GPG concepts. Would you mind taking a look and seeing if it's valid? – Maros Feb 06 '15 at 21:23
  • Hah, made edits at almost the same time. – AJAr Feb 06 '15 at 21:25
  • Haha. What a coincidence. – Maros Feb 06 '15 at 21:28
  • What kind of app are you making, btw? Just curious since at first I thought it was a web app. – AJAr Feb 06 '15 at 21:32
  • It's a typical Rails app. I just made that script for testing purposes. – Maros Feb 06 '15 at 21:35
  • Oh, alright. In that case, I think it might be better to have them decrypt a message than encrypt one. The margin for error is a bit lower, plus (depending on your audience) some users may not know how to sign messages even though they know how to encrypt them. A lot of different interfaces out there for PGP. – AJAr Feb 06 '15 at 21:42
  • But isn't it possible for an attacker to grab [another user's key](http://bitcoin-otc.com/viewgpg.php?nick=nanotube) and sign the message with that to claim to be that user? – Maros Feb 06 '15 at 21:57
  • They can't sign with just the public key. – AJAr Feb 06 '15 at 21:58
  • I think the reason why #bitcoin-otc checks GPG the way it does (sig request instead of decryption request) is because sig verification is a much, much faster op than encryption. That said, one is IRC and the other is a website; it can't very easily use a CAPTCHA, but you can to mitigate the risk of DOS attacks. – AJAr Feb 06 '15 at 23:02
  • That makes sense. How would this work if I got the user to decrypt a message? Wouldn't I first need to encrypt it in a way that only he can decrypt it as the holder of the secret token? Wouldn't I also need access to that secret token to do the encryption? Sorry, I'm pretty new to GPG. – Maros Feb 06 '15 at 23:08
  • Let's chat about it (http://chat.stackexchange.com/rooms/20905/discussion-between-ajar-and-maros-hluska). Getting crowded on the comments here. – AJAr Feb 06 '15 at 23:14