Java: Base64 Encode a String using a key

隐身守侯 提交于 2020-02-02 23:43:07

问题


Hi I have data and a key (both strings). The data needs to be encode using the key using Base64. Can some one give me a sample code.


回答1:


Base64 is not for 'encoding with a key'. It is simply a encoding scheme: you can use Base64 to encrypt and decrypt strings without any extra's. It's just for very (very) basic security usages.




回答2:


you can xor the data with your key and then base64 encode it.

var key = "mykey";
var mydata = "some long text here";
var output = '';

for (var i = 0, len = mydata.length; i < len; i++) {
   output += String.fromCharCode(mydata.charCodeAt(i) ^ key.charCodeAt(i % key.length));
}

and then you encode 'output' to base64 using some function from somewhere




回答3:


If you need to encode with Base64 using a key, then actually it is not hard to do this, even if it is not defined in the standard.

Base64 uses an alphabet of 64 symbols. The first 62 symbolss are small and capital letters of English alphabet, plus digits from 0 to 9. The final 2 characters most commonly are + and /, but these can differ between implementation.

So now understand, that when you break your string into bits, and regroup them using 6 bits instead of 8 per symbol, you will alway be able to look up a symbol in your alphabet, because 6 bit numbers have exactly 64 different possible values. Base64 just enumerates symbols from %000000 (0) to 111111 (63). But you could use a key during this symbol lookup. Say your 6 bit number is %000011 (3), thus it would index the 4th symbol in your alphabet. But now you can use your key to modify that index, move it left or right by (for example) the number of positions equal to the ASCII code of your key's character (8 bit number). Whenever your index goes out of range (below 0 or above 63) you just teleport it to the opposite side of the range. And if you moved the index right during encoding, use left direction for decoding (and vice versa). Basically you are scrambling the symbol lookup with a pattern defined by the characters of your key.

There you go, you just use Base64 encoding with a key (rather then first keying the input then encoding). You're welcome.

And since you asked for a code sample, below is a quick sample in Object Pascal, that I wrote. This code could be faster if you first allocate memory for the final string and then write into it, instead of concatenating to the string in a loop, which re-allocates memory every time - but that you can figure out yourself, if you have need for better performance:


const 
      C_ALPHABIG      = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
      C_ALPHASMALL    = 'abcdefghijklmnopqrstuvwxyz';
      C_ALPHA         = C_ALPHABIG+C_ALPHASMALL;
      C_DIGITS        = '0123456789';
      C_SYMBOLS       = '+/';
      C_ALPHABET      = C_ALPHA+C_DIGITS+C_SYMBOLS;

    type 
      TIndexShiftDirection = (isdLeft, isdRight);

      Function ShiftSymbolIndex(const AIndex: integer; const AKey: string; var ACurrentKeyPos: integer; const ADirection: TIndexShiftDirection): integer;
       begin
         Result := AIndex; if(AKey='')then exit;
         if(ACurrentKeyPosLength(AKey))then ACurrentKeyPos := 1;
         if(ADirection=isdRight)
           then begin
                  Result := Result+Ord(AKey[ACurrentKeyPos]);
                  if(Result>64)then Result := Result mod 64;
                  if(Result=0)then Result :=64;
                end
           else begin
                  Result := Result-Ord(AKey[ACurrentKeyPos]);
                  if(Result=Length(AKey))
           then ACurrentKeyPos := 1
           else inc(ACurrentKeyPos);
       end;

      Function  Encode64(const s: string; const Key: string): string;
       var
         i,n,p,k : integer;
         a,b,c,d : byte;
       begin
         Result   := ''; k := 1; if(s='')then exit;
         n := Length(s)div 3;
         if(n>0)then for i:=0 to n-1 do
           begin
             p := (i*3)+1;
             a := (ord(s[p])shr 2); inc(a);
             b := ((ord(s[p])and %00000011)shl 4)+(ord(s[p+1])shr 4); inc(b);
             c := ((ord(s[p+1])and %00001111)shl 2)+(ord(s[p+2])shr 6); inc(c);
             d := ord(s[p+2])and %00111111; inc(d);
           //
             a := ShiftSymbolIndex(a,key,k, isdRight);
             b := ShiftSymbolIndex(b,key,k, isdRight);
             c := ShiftSymbolIndex(c,key,k, isdRight);
             d := ShiftSymbolIndex(d,key,k, isdRight);
           //
             Result := Result
                     + C_ALPHABET[a]
                     + C_ALPHABET[b]
                     + C_ALPHABET[c]
                     + C_ALPHABET[d];
           end;
         n := Length(s)-(n*3);
         if(n=0)then begin {Result := Result+'0';} exit; end;
         case n of
           1: begin
                p := Length(s);
                a := (ord(s[p])shr 2);         inc(a); a := ShiftSymbolIndex(a,key,k, isdRight);
                b := (ord(s[p])and %00000011); inc(b); b := ShiftSymbolIndex(b,key,k, isdRight);
                Result := Result
                        + C_ALPHABET[a]
                        + C_ALPHABET[b]
                        {+ '2'};//if Length(endoced_str)mod 4 = 2, then this case is true
              end;
           2: begin
                p := Length(s)-1;
                a := (ord(s[p])shr 2);
                b := ((ord(s[p])and %00000011)shl 4)+(ord(s[p+1])shr 4);
                c := (ord(s[p+1])and %00001111);
                inc(a); a := ShiftSymbolIndex(a,key,k, isdRight);
                inc(b); b := ShiftSymbolIndex(b,key,k, isdRight);
                inc(c); c := ShiftSymbolIndex(c,key,k, isdRight);
                Result := Result
                        + C_ALPHABET[a]
                        + C_ALPHABET[b]
                        + C_ALPHABET[c]
                        {+ '4'};//if Length(endoced_str)mod 4 = 3, then this case is true
              end;
         end;
       end;

      Function  Decode64(const s: string; const Key: string): string;
       var
         n,i,p,k : integer;
         a,b,c,d : byte;
       begin
         Result := ''; k:=1; if(s='')then exit;
         n := Length(s)div 4;
         if(n>0)then for i:=0 to n-1 do
           begin
             p := (i*4)+1;
             a := Pos(s[p],C_ALPHABET);   a := ShiftSymbolIndex(a,key,k, isdLeft);
             b := Pos(s[p+1],C_ALPHABET); b := ShiftSymbolIndex(b,key,k, isdLeft);
             c := Pos(s[p+2],C_ALPHABET); c := ShiftSymbolIndex(c,key,k, isdLeft);
             d := Pos(s[p+3],C_ALPHABET); d := ShiftSymbolIndex(d,key,k, isdLeft);
             if(a*b*c*d=0)then begin Result := ''; exit; end; //cannot be, if symbols are valid
             Result := Result
                     + chr(((a-1)shl 2) + ((b-1)shr 4))
                     + chr((((b-1)and %001111)shl 4) + ((c-1)shr 2))
                     + chr((((c-1)and %000011)shl 6) + (d-1));
           end;
         n := Length(s)mod 4;
         if(n=0)then exit;
         case n of
           2: begin
                p := Length(s)-1;
                a := Pos(s[p],C_ALPHABET);   a := ShiftSymbolIndex(a,key,k, isdLeft);
                b := Pos(s[p+1],C_ALPHABET); b := ShiftSymbolIndex(b,key,k, isdLeft);
                if(a*b=0)then begin Result := ''; exit; end; //cannot be, if symbols are valid
                Result := Result
                        + chr(((a-1)shl 2) + (b-1));
              end;
           3: begin
                p := Length(s)-2;
                a := Pos(s[p],C_ALPHABET);
                b := Pos(s[p+1],C_ALPHABET);
                c := Pos(s[p+2],C_ALPHABET);
                if(a*b*c=0)
                  then begin Result := ''; exit; end; //cannot be, if symbols are valid
                a := ShiftSymbolIndex(a,key,k, isdLeft);
                b := ShiftSymbolIndex(b,key,k, isdLeft);
                c := ShiftSymbolIndex(c,key,k, isdLeft);
                Result := Result
                        + chr(((a-1)shl 2) + ((b-1)shr 4))
                        + chr((((b-1)and %001111)shl 4) + (c-1));
              end;
           else Result := '';
         end;
       end;  

Note the function ShiftSymbolIndex - this is the symbol lookup scrambler, it can either move symbol index right, or left. I use right in the encoder, and left in the encoder, but it's all up to you. If you skip the key argument in either Encode64 or Decode64 function (or if you pass an empty string key), then you will end up with a default Base64 encoding/decoding.

Also, this encoder does not append padding ("=" characters) to the base64 encoded string. The padding is not needed to decode, unless your decoder works in a strict mode (this encoder isn't) - but that, you can figure out yourself.




回答4:


You can use apache commons Codec library's Base64 class. Here's the homepage for it and the download page.




回答5:


You could use a symmetric binary encryption algorithm such as Twofish or RC4 which utilizes such a key, then encode the result in base-64.




回答6:


Base64 doesn't include a feature to encrypt with key. You can use AES, DES etc to encrypt first and then use base64 to encode.



来源:https://stackoverflow.com/questions/6347780/java-base64-encode-a-string-using-a-key

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!