5

Maybe I'm crazy, but it looks like the famous code to run Base64 in VB inserts a newline character (ascii 10) at the 73rd position, which subsequently makes the encoded string invalid for Basic authentication - or anything else for that matter.

Original code:

Function Stream_StringToBinary(Text)
  Const adTypeText = 2
  Const adTypeBinary = 1

  'Create Stream object
  Dim BinaryStream 'As New Stream
  Set BinaryStream = CreateObject("ADODB.Stream")

  'Specify stream type - we want To save text/string data.
  BinaryStream.Type = adTypeText

  'Specify charset For the source text (unicode) data.
  BinaryStream.CharSet = "us-ascii"

  'Open the stream And write text/string data To the object
  BinaryStream.Open
  BinaryStream.WriteText Text

  'Change stream type To binary
  BinaryStream.Position = 0
  BinaryStream.Type = adTypeBinary

  'Ignore first two bytes - sign of
  BinaryStream.Position = 0

  'Open the stream And get binary data from the object
  Stream_StringToBinary = BinaryStream.Read

  Set BinaryStream = Nothing
End Function


Function Base64Encode(sText)
    Dim oXML, oNode

    Set oXML = CreateObject("Msxml2.DOMDocument.3.0")
    Set oNode = oXML.CreateElement("base64")
    oNode.dataType = "bin.base64"
    oNode.nodeTypedValue =Stream_StringToBinary(sText)
    Base64Encode = oNode.text
    Set oNode = Nothing
    Set oXML = Nothing
End Function

'------------------- and here goes the encoding -----------------------
  strEnc = Base64Encode( "AVERYLONGUSERNAMEHELLOTHE123:AVERYLONGPASSWORDWHYAREYOUSOLONGREALLYANNOY123")
'----------------------------------------------------------------------    

RESULT:

QVZFUllMT05HVVNFUk5BTUVIRUxMT1RIRTEyMzpBVkVSWUxPTkdQQVNTV09SRFdIWUFSRVlP
VVNPTE9OR1JFQUxMWUFOTk9ZMTIz

Looks like this occurs on very long UID/PWD pairs.

Has anyone encountered this?

user692942
  • 16,398
  • 7
  • 76
  • 175
access_granted
  • 1,807
  • 20
  • 25

1 Answers1

8

This is because of how the Base64 encoding deals with long strings.

From RFC 2045 - 6.8 Base64 Content-Transfer-Encoding
The encoded output stream must be represented in lines of no more than 76 characters each. All line breaks or other characters not found in Table 1 must be ignored by decoding software. In base64 data, characters other than those in Table 1, line breaks, and other white space probably indicate a transmission error, about which a warning message or even a message rejection might be appropriate under some circumstances.

Because it is adding the vbLf (Chr(10)) after the encode should mean you are safe to just remove it using

strEnc = Replace(strEnc, vbLf, "")

Some languages have a "no wrapping" argument that can be passed to stop the Linefeed being added after the 76th character but I don't know of one in the Microsoft XMLDOM implementation, noted here Base64 -- do we really want/need line breaks every 76 characters? it looks as though it was suggested but there is no evidence it was ever implemented.

user692942
  • 16,398
  • 7
  • 76
  • 175
  • Good catch. Beats me why MS inserts a break on the 73rd though. I spent quite some time with failing Basic Auth over SSL only to discover the special char that made it into the string. – access_granted Jan 24 '17 at 21:34
  • @access_granted it is a weird one to be honest I'm guessing they didn't want to exceed the 76 character maximum so decided to cut it at 72 instead. – user692942 Jan 24 '17 at 21:36
  • 5
    Base64 Encoding does not limit the line length. That 76 character limit and the RFC you quoted belong to MIME. Instead [RFC 4648](https://tools.ietf.org/html/rfc4648) must be referenced, specifically [Section 3.1](https://tools.ietf.org/html/rfc4648#section-3.1). On the other hand, 72 character limit is a historic practice that remains from the days of typwriters. As a fun fact about that, you can check the maximum length of lines in those RFC files. – Kul-Tigin Jan 25 '17 at 01:35
  • 1
    @access_granted MSXML's `bin.base64` is an [XDR Schema Data Type](https://msdn.microsoft.com/en-us/library/ms256121(v=vs.85).aspx) encoded in MIME style. So this is an expected behavior (it does not matter 72 or 76) and replacing `vbLf`s just works. I think you should mark the answer as accepted. – Kul-Tigin Jan 25 '17 at 01:35