hossam
hossam

Reputation: 21

Convert.ToBase64String/Convert.FromBase64String doesn't return the original string value

"encryptedHelloWorld=" ==
      Convert.ToBase64String(
         Convert.FromBase64String("encryptedHelloWorld="))

This statement returns false

Convert.ToBase64String(Convert.FromBase64String("encryptedHelloWorld="))

return "encryptedHelloWorlc="

Any idea why?

Upvotes: 0

Views: 284

Answers (1)

user2864740
user2864740

Reputation: 61875

The original value of encryptedHelloWorld= is not correctly base-64 encoded.

The last "d" contains an extra bit that is ignored on extraction in this context, where it occurs immediately before padding. A stricter base-64 decoder could validly throw an error.

Minimal failing input cases include rld= or abq=. Only the last portion with the padding is relevant, as discussed below.

Consider that each output character of base-64 character represent 6 bits each.

Thus the information encoded in rld= is:

  • r - 6 bits
  • l - 6 bits
  • d - 6 bits (4 relevant = "c" + 2 extra)
  • = - n/a

This must be extracted into 2 bytes (8 + 8 = 16 bits).

However, 6 + 6 + 6 = 18 bits and is not a multiple of 8. There are 2 extra bits which differentiate "c" from "d" in the initial base-64 value which do not reflect the actual encoded information.

During the decoding, the .NET decoder implementation silently drops the two extra bits in the "d", as they have nowhere to go. (This is also true for cases like abq= as "q" > "c"; note that capital letters are ordered first in the base-64 output space so "Q" < "c".)

In the normal case without padding, every 4 base-64 characters decode in 3 bytes evenly, which is why this particular issue is only present at the end of a base-64 string which is not an even multiple of 4 base-64 characters (excluding padding characters).

Upvotes: 3

Related Questions