How to decode base64 url in python?

前端 未结 9 1373
一个人的身影
一个人的身影 2020-12-28 15:24

For Facebook fbml Apps Facebook is sending in a signed_request parameter explained here:

http://developers.facebook.com/docs/authentication/canvas

They have

相关标签:
9条回答
  • 2020-12-28 15:50

    This is the right solution. In python there is base64.b64encode but that only base64 encodes and its is different from base64 url encoding. Here is the right set to of steps to convert form base64encoded to base64urlencoded string:
    1. From the resultant string, replace "/" with "_" and "+" with "-"
    2. Strip the trailing "==".

    Et voila! That will make it a valid string for base64 url decoding. Btw, that link in @dae.eklen 's answer above is broken now.

    0 讨论(0)
  • 2020-12-28 15:54

    I have shared a code snippet for parsing signed_request parameter in a python based facebook canvas application at http://sunilarora.org/parsing-signedrequest-parameter-in-python-bas:

    import base64
    import hashlib
    import hmac
    import simplejson as json
    
    def base64_url_decode(inp):
        padding_factor = (4 - len(inp) % 4) % 4
        inp += "="*padding_factor 
        return base64.b64decode(unicode(inp).translate(dict(zip(map(ord, u'-_'), u'+/'))))
    
    def parse_signed_request(signed_request, secret):
    
        l = signed_request.split('.', 2)
        encoded_sig = l[0]
        payload = l[1]
    
        sig = base64_url_decode(encoded_sig)
        data = json.loads(base64_url_decode(payload))
    
        if data.get('algorithm').upper() != 'HMAC-SHA256':
            log.error('Unknown algorithm')
            return None
        else:
            expected_sig = hmac.new(secret, msg=payload, digestmod=hashlib.sha256).digest()
    
        if sig != expected_sig:
            return None
        else:
            log.debug('valid signed request received..')
    return data
    
    0 讨论(0)
  • 2020-12-28 15:55

    Surprising, but currently accepted answer is not exactly correct. Like some other answers stated, it's something called base64url encoding, and it's a part of RFC7515.

    Basically, they replaced '+' and '/' chars by '-' and '_' respectively; and additionally removed any trailing '=' chars, because you can always tell how many chars you're missing, just by looking at the encoded string length.

    Here's illustrative example from RFC7515 in C#:

     static string base64urlencode(byte [] arg)
     {
       string s = Convert.ToBase64String(arg); // Regular base64 encoder
       s = s.Split('=')[0]; // Remove any trailing '='s
       s = s.Replace('+', '-'); // 62nd char of encoding
       s = s.Replace('/', '_'); // 63rd char of encoding
       return s;
     }
    
     static byte [] base64urldecode(string arg)
     {
       string s = arg;
       s = s.Replace('-', '+'); // 62nd char of encoding
       s = s.Replace('_', '/'); // 63rd char of encoding
       switch (s.Length % 4) // Pad with trailing '='s
       {
         case 0: break; // No pad chars in this case
         case 2: s += "=="; break; // Two pad chars
         case 3: s += "="; break; // One pad char
         default: throw new System.Exception(
           "Illegal base64url string!");
       }
       return Convert.FromBase64String(s); // Standard base64 decoder
     }
    
    0 讨论(0)
提交回复
热议问题