2

I have a base64 string like this:

MIIEpAIBAAKCAQEAtp/Uo28kOjROL50aajnpK25CJoVoic2bqqu6OS2baWWD9fT2\nESqq8mbFxYN3O7JXbs+74YpTdg1jSUALOz9zj/H2eCF71QYvoHmdoi0iiQuy3gS1\n6YczVvBvinSwfEnO6Wi/Xx6AC8urdreUR0c+5cNNSqI9oyrwA4m/XrFwR6ptT9oy\nyahrVJdjA2Wdf+O4/0lW+jrMw+s\nQptfu4QslKhDnRUFu4ALqm3nypD/ojGjFCEl5poiBMMztqIpE7f9t+IBY/zJbOBP\nI+sHVgwH/pJbi0CqIiDNIEiXsLDERTldzvA4DQIDAQABAoIBAFu+IVlVLRLcUebT\neoCgxQUfZ7XoUSLhGnF7wZqV0bv51ngJ7k+jaqtJe9MEfzKLHic5zn24OsNUaGtU\n9A94ibpnaFTjJU1XxTdNwSXGnNHSAbJNFYHSfLURJkec5Uga4Aobp//F17eVQnbq\nNGA2Z1+PZFW4+VPt7xMn8O5GH0ywdFhj4PI+z+UT0j1ezebjzDM2FoKwjfvA0wHg\nbZuyFjb0EBNsaW9y1quh2sSaHAFATYoTLG3ArM/Ue4Fr/Qom0/5N3uusifMdWEcA\nw7/yiI9D7Q4XsqoZ9gqAhXOcWgJmjvsx66zqUbArw/HmqIy5/vQfoZV78ux2iyZP\nO9n68AECgYEA6GP5Ns8Zfgm9Y7J5OxjgGwwQYZziKGysnYIe2N6y9jbjXdjsTtTH\nJKeeM+eHL3Mq2yrYj9m3bACE/uNQ/4o+V+hvVQusN+bMpY5YGHm4KiGL0ieNYs3B\nA6LLGni7itMY5SC9g7Rm5tlAvUmv38NTKcS47Wz1YKrnhId4x5eWPAECgYEAyS2J\nB8/6+C3jowJWJoguLKWWeEF5sPe9IWTqWxoUuJRLaSoKTWl0VKPB60DZZEpbPh2n\nuQlfaRnbt/YZBIeBqnrZzqiO5iTDDtw8zOa0B+DLv9OX9I4dzbQ+PtH/CRH6cDst\nhrMUUqW5K56za+gH8iiyvBAxjJG11QctUdIh0GZdgdhkW2YFYO\nClWYyCaqhfWOeJOjtQNgBGleXRF/4EJRNJP8wTuXVK+Vnrynq6dk2tyb77TyLRTZ\nF5ZsrQKBgQCaNIpP1tGYpYTfFny5xQ8aY5e6Bd3/aC5Ays8wYb8oAPYwH9AeqWY2\nsistzq9ARRbvwXzl45HzRKYoWVd1D0D5yOwxFOW++VD3luXH1UpEB1bvxHrpIwbD\ngg9jhO9K1yri6JGA5ENx5InrvKsqodP/llszVJysBlUeAcwMo2gjNA==

Please note that above string is private key so some characters have been purposely removed.

And I am trying to convert it in bytes:

def convertToBase64(privateKeyB64: String) = {
    val bytesArray = java.util.Base64.getDecoder.decode(privateKeyB64.replaceAll("\\r\\n|\\r|\\n", ""))
    import java.security.KeyFactory
    import java.security.spec.PKCS8EncodedKeySpec
    val spec = new PKCS8EncodedKeySpec(bytesArray)
    // create key form spec
    val keyFactory = KeyFactory.getInstance("RSA")
    keyFactory.generatePrivate(spec)

  }

The above code fails at the step: val bytesArray = java.util.Base64.getDecoder.decode(privateKeyB64.replaceAll("\\r\\n|\\r|\\n", "")) with the error:

Exception in thread "main" java.lang.IllegalArgumentException: Illegal base64 character 5c

I am not sure what is it complaining about exactly? What does 5c mean in base64?

Shivam Sahil
  • 4,055
  • 3
  • 31
  • 62
  • Looks like a similar problem: https://stackoverflow.com/questions/28584080/base64-java-lang-illegalargumentexception-illegal-character – QBrute Oct 26 '22 at 08:18
  • 5c is the ASCII code of \. I see you tried to remove \r and \n but there seems to be a \ left in the string. – jps Oct 26 '22 at 08:21
  • Don't do that `replaceAll` on `Base64`. There is just wrong and will mess up the `Base64` encoded string. Also, keep in mind strings in java are utf-16. – sarveshseri Oct 26 '22 at 09:06
  • Your base64 has been done wrong. You need to do it right. Fiddling about with a corrupt base64 string is not going to help you – g00se Oct 26 '22 at 09:58
  • 1
    If, for some reason, you can't get it again uncorrupted, try `replaceAll("\\\\n", "");` – g00se Oct 26 '22 at 10:10

1 Answers1

2

Perhaps you should double check the encoding of your Base64 data. Base64 data can come encoded in different formats as defined in RFC 4648 and RFC 2045. Java has different implementations for three different types of encoding as documented in the java.util.Base64 JavaDoc, Basic, MIME and URL-safe. From a couple of experiments it looks like yours is in the MIME format, so the following should work:

def convertToBase64(privateKeyB64: String) = {
  val bytesArray = java.util.Base64.getMimeDecoder.decode(privateKeyB64)
  val spec = new java.security.spec.PKCS8EncodedKeySpec(bytesArray)
  java.security.KeyFactory.getInstance("RSA").generatePrivate(spec)
}

I tried to run it locally but now the problem shifts towards generating the private key, so there may be some mismatch between the key you are generating and the expected format. Perhaps it's not a valid PKCS#8?

stefanobaghino
  • 11,253
  • 4
  • 35
  • 63
  • Thank you so much @stefanobaghino. You have no idea how much helpful this was to me. When I tried out your code, it gave me a new error: `Algid parse error, not a sequence` and then I checked https://stackoverflow.com/questions/6559272/algid-parse-error-not-a-sequence and finally its working now. Thanks a ton! just made my difficult day. – Shivam Sahil Oct 26 '22 at 10:57
  • Btw, is it possible to perform perm steps programatically instead of using cli? I had to generate those variables manually through terminal commands: `openssl pkcs8 -topk8 -inform PEM -in private.pem -out private_key.pem -nocrypt`? – Shivam Sahil Oct 26 '22 at 10:58
  • 1
    Java has APIs for that as well, you can start from https://docs.oracle.com/javase/tutorial/security/apisign/step2.html – stefanobaghino Oct 26 '22 at 12:22