1

I have a PHP script that creates a QR code out of a username and timestamp. I need to prove the QR code came from my server so I am encrypting the username and timestamp with a private RSA key. In order to get it into the QR code I am then base64 encoding it.

I am trialling it with Android first. I can get the string out of the QR code but when I base64 decode it in Android, it returns null. After debugging it seems it's because there are two whitespaces in the string. When the decoder comes to check the illegal characters are divisible by 4, it obviously fails. Getting desperate I removed the whitespaces but then it changed the length so the calculations still didn't work out. Can I change the whitespace for a 'safe' character? Or is the particular encode/decode pair not compatible??

PHP code:

$data = base64_encode($username."`".$timestamp); $fp = fopen("private.pem", "r"); $private_key = fread($fp, 8192); fclose($fp); openssl_private_encrypt($data, &$encrypted_data, $private_key); $encrypted_data_64 = base64_encode($encrypted_data); // create QR code 

Android code:

String s = data.getStringExtra("SCAN_RESULT"); byte[] b = Base64.decode(s.toCharArray()); // b is null at this point 

Base64 code that it bugs out on:is

// Check special case int sLen = str != null ? str.length() : 0; if (sLen == 0) return new byte[0]; // Count illegal characters (including '\r', '\n') to know what size the returned array will be, // so we don't have to reallocate & copy it later. int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...) for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out. if (IA[str.charAt(i)] < 0) sepCnt++; // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045. if ((sLen - sepCnt) % 4 != 0) return null; 
8
  • Assuming you can open the key, the PHP-side looks OK, you've checked that $encrypted_data_64 is not an empty string? Don't know how to fix Andriod though :) Commented Jul 26, 2011 at 23:22
  • Theoretically it shouldn't make a different but what about using String.getBytes() or Base64.decode(String, int)? Commented Jul 26, 2011 at 23:47
  • Can you post the code somewhere? I'm wondering where those extra spaces are coming from ... if they're in the code or getting inserted during the decode ... Commented Jul 27, 2011 at 3:57
  • The spaces are in $encrypted_data_64 (which isn't null). Can post code when I get home tonight. Any particular code? Commented Jul 27, 2011 at 11:29
  • I meant post the QR code image. But if the PHP variable has spaces in it, it sounds like something in PHP. "Pure" base64 should just be the base64 set with possible '=' characters at the end to round out the length as necessary. Commented Jul 27, 2011 at 14:26

1 Answer 1

1

PHP base64 encode uses the '+' symbol. When this gets put into a QR code, the '+' comes through as space. Replaced ' ' with '+' and it got decoded fine.

Sign up to request clarification or add additional context in comments.

3 Comments

Are you sticking this in a URL? That's not a QR thing, it's an HTTP/URL thing. Lookup Base64 on Wikipedia, in particular at "base64url". If this looks like/is in a URL, you're better off replacing '+' with '-' and and '/' with '_' before sticking it in a URL and after getting it back from the URL.
No this isn't a URL, just data used by my app.
Odd. Certainly nothing about native QR encoding should make any changes to the data, any character substitution.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.