Шифрование иностранных символов с помощью библиотеки JavaScript не работает - PullRequest
1 голос
/ 25 февраля 2012

У кого-нибудь было удачное шифрование иностранных символов любой библиотекой javascript?

Я шифрую иностранные символы с помощью библиотеки jCryption v. 1.4 (алгоритм RSA).Похоже, библиотека плохо работает с иностранными символами (я использую cp1251).Шифрование хорошо работает с ASCII / английскими символами, но я получаю искаженные символы после расшифровки чужих.

Я считаю, что проблема заключается в том, как jCryption преобразовывает строку символов в байты.Он сдвигает символ только на 8 битов и & 2 символа вместе.Иностранные символы занимают> 8 бит наверняка.

Любые идеи будут оценены!
Дмитрий

Ответы [ 2 ]

1 голос
/ 26 февраля 2012

Вот код base64 для 16-битных символов Unicode (javascript):

var Base64 = {};  // Base64 namespace

Base64.code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

Base64.encode = function(str) { 
    var o1, o2, bits, h1, h2, h3, h4, h5, d6, e=[], pad = '', c, plain, coded;
    var b64 = Base64.code;

    plain = str;

    c = plain.length % 2;  // pad string to length of multiple of 3
    if (c > 0) { while (c++ < 2) { pad += '==='; plain += '\0'; } }

    for (c=0; c<plain.length; c+=2) {  // pack 2 hexadecets into 6 hexets
        o1 = plain.charCodeAt(c);
        o2 = plain.charCodeAt(c+1);

        bits = o1<<16 | o2;

        h1 = bits>>26 & 0x3f;
        h2 = bits>>20 & 0x3f;
        h3 = bits>>14 & 0x3f;
        h4 = bits>>8 & 0x3f;
        h5 = bits>>2 & 0x3f;
        d6 = bits & 0x3;

        // use hextets to index into code string
        e[c/2] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4)
            + b64.charAt(h5) + b64.charAt(d6);
    }
    coded = e.join('');  // join() is far faster than repeated string concatenation in IE

    // replace 'A's from padded nulls with '='s
    coded = coded.slice(0, coded.length-pad.length) + pad;

    return coded;
}

Вот код base64 для 16-битных символов Unicode (java):

private static String BASE64_CODE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
private String decodeBase64(String b64Str) {
    try {
        String decodedBase64 = "";

        for (int c = 0, b=0; c < b64Str.length(); c+=6, b+=4) {
            // unpack 5 hexets and 2-bit into 4 octets
            int h1 = BASE64_CODE.indexOf(b64Str.charAt(c));
            int h2 = BASE64_CODE.indexOf(b64Str.charAt(c + 1));
            int h3 = BASE64_CODE.indexOf(b64Str.charAt(c + 2));
            int h4 = BASE64_CODE.indexOf(b64Str.charAt(c + 3));
            int h5 = BASE64_CODE.indexOf(b64Str.charAt(c + 4));
            int d6 = BASE64_CODE.indexOf(b64Str.charAt(c + 5));

            int bits =  h1<<26 |  h2<<20 |  h3<<14 | h4<<8 | h5<<2 | (d6 & 0x3);
            byte o1 = (byte) (bits>>>24 & 0xff);
            byte o2 = (byte) (bits>>>16 & 0xff);
            byte o3 = (byte) (bits>>>8 & 0xff);
            byte o4 = (byte) (bits & 0xff);

            String partialDecodedStr = new String(new byte[] {o1, o2}, "UTF-16");

            //take care of padding
            // - if BASE64_CODE.indexOf(b64Str.charAt(c + 3)) == 64 OR b64Str.charAt(c + 3) == '='
            if (h4 == 0x40) {
               //This 16-bit char was padding: get rid of it
            }
            else
                partialDecodedStr = partialDecodedStr.concat(new String(new byte[] {o3, o4}, "UTF-16"));

            decodedBase64 = decodedBase64.concat( partialDecodedStr);
        }

    return decodedBase64;
}
catch (UnsupportedEncodingException e) {
    //TODO log4j
    e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
    throw new RuntimeException("Unable to decode base64.");
}
}
1 голос
/ 25 февраля 2012

Вы можете сначала попытаться закодировать сообщение Base64, а затем зашифровать.Это позволит убедиться, что на входе есть только символы ascii.

Так что ваш алгоритм, вероятно, будет выглядеть примерно так: псевдокод.

Encryption
input = "text";
input = base64Encode(input); //there's lots of implementations of this online
cipher = encodeWithJcrypt(input);

Decryption
text = decodeWithJcrypt(cipher);
text = base64Decode(text);
...