#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2012
    Posts
    3
    Rep Power
    0

    RSA Verification in Browser for Chiptune Website, padding needed?


    Hi! I'm the developer of a website for creating chiptune music called beepbox. I'm not allowed to post URLs yet since I'm a new user, but you can google it if you're interested.

    I'm investigating ways to provide some notion of authenticity when people publish songs through my interface. I've been doing a bunch of research on cryptography to come up with a plan, but I'm not a professional security expert so I definitely need a few more eyeballs to take a look at it before I commit to it. I'd appreciate any advice you guys have, including connections with other people who know what they're talking about.

    There are two problems I'm trying to solve:

    1. You should not be able to take a song you wrote and claim someone else wrote it. I'm actually not too worried about this kind of abuse (who would even do that and what would it accomplish?) so my solution doesn't need to be 100% secure here, just difficult. My current plan is that authors provide a "password" that gets hashed and then visualized as an avatar, much like Gravatar defaults. So if two songs have different avatars, then either they were submitted by different people or one person figured out the other's password.

    2. You should not be able to take someone else's song and claim that you wrote it first. (You are welcome to publish derived songs, since imitation is an important part of learning, not to mention flattery.) I imagine this sort of abuse would be more likely and more damaging. So in my plan, when you publish a song, the date is provided by a server acting as an authority, so nobody can lie about when they published a song. It sounds like we're gonna need a digital signature with the private key on the server, asserting that this song was published by someone claiming to be this author on this date.

    My plan is made trickier by the self-imposed, unorthodox constraint that I don't store any user-data on my server. There are a bunch of reasons for this constraint, but the short version is that I want to see how much I can rely on URL fragments to share data. At the moment, all song data is represented in the URL after the # mark, while the server has entirely static content, and I'd like to keep it that way if possible. This means that the only secret I have to work with is a static private key on the server. Everything else is public, including the entirety of all previously signed messages and their signatures.

    My current plan is to create a form on my website where you can submit your song data to the server, along with your name and password. The server appends the current date and maybe some padding to the message, hashes all of that (SHA256?) and signs it with a private key stored on the server using RSA (vanilla?) signing, and returns the full message and the signature to the author. The author may now share the message and signature together in a URL fragment at my domain. When someone else goes to that URL, my server will give them a static web page with some javascript and/or actionscript that knows how to interpret the rest of the URL, verifying it with the public key and then displaying the author, the avatar, the publish date, and the song itself.

    Unfortunately I'm having trouble finding a browser API for verifying the signature. I've read that doing RSA signing without any padding is Bad. People recommend using some scheme like RSASSA-PSS. I'm not aware of any reputable browser-based RSA signature verifier that supports such advanced signature verification. I understand that javascript security is perceived as a dead end, but in my case there's nothing in the browser that absolutely needs to be kept a secret. I'm not looking for privacy, just authentication of a widely available public message+signature with a widely available public key.

    On my server, I'm using PyCrypto, which supports vanilla RSA signing as well as some more advanced schemes. On the browser, however, the best option I've found so far is AS3Crypto, which seems to support vanilla RSA verification and also claims to support padding but isn't very clear on what kind of padding it supports and hasn't been maintained. Any other suggestions?

    It's not hard for me to add my own padding to a message on the server before signing it, in fact I'm already adding a date to the message and could easily add some random gibberish. Assuming I can get vanilla RSA to work, what do I need to know about padding to make sure I'm preventing forgery?

    Sorry about the wall of text, and thanks in advance for any help!
  2. #2
  3. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2012
    Posts
    3
    Rep Power
    0
    A quick update: I've been playing with PyCrypto and As3Crypto and I've confirmed that I can perform vanilla RSA signing in the former and verify it in the latter. Currently investigating padding options in As3Crypto but so far it looks grim.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2012
    Posts
    3
    Rep Power
    0
    Alright, turns out not even PyCrypto supports RSA signature padding, at least not the version I'm using. (PyCrypto 2.3, integrated with Google App Engine.)

    So it sounds like it's up to me to do the padding myself. I understand that nobody recommends DIY cryptography, which is why I'm here asking questions to make sure I get it right.

    So I see that there's basically two kinds of RSA signature padding in use: PSS and PKCS-v1.5. PSS is theoretically stronger, but given our present understanding it sounds like both are equally hard to crack. PKCS-v1.5 is probably good enough for my purposes, and fortunately it looks like it's dead simple to implement.

    Technically you're supposed to put the hash inside some "DER" encoding before padding, but I get the impression that this is purely for documentation rather than for any cryptography reasons, right? Since I'm doing the both the signing and verification parts internally, I figure I'll skip that step and just add padding to the hash directly.

    In that case all I have to do is add these bytes to the front of the hash before signing it with RSA until it's 256 bytes long:
    00 || 01 || ff || ff || ff || ... || ff || 00 || hash
    I wonder if it's a terrible idea to use random bytes instead of all those ff bytes... Yeah, better not chance it I guess.

    So how about it? Are you guys laughing at my naiveté yet? :P

IMN logo majestic logo threadwatch logo seochat tools logo