Ad

Escaping From "/" Character In Dart Encryption

- 1 answer

I have an encryption class in Dart, which will encrypt User ID for posting it to MariaDB table with REST (Post Request, ? and * is placeholder, these are different in my real code.):

import 'package:encrypt/encrypt.dart';
//import 'dart:convert' as convert;

    class Security {
      ///Key
      static final _key =
          Key.fromUtf8('********************************'); //32 chars
      static final iv = IV.fromUtf8('????????????????'); //16 chars
    
      ///encrypt, [text] is data.
      static String encryptMyData(String text) {
        final e = Encrypter(AES(_key, mode: AESMode.cbc));
        final encryptedData = e.encrypt(text, iv: iv);
        return encryptedData.base64;
      }
    
      ///decrypt, [text] is data.
      static String decryptMyData(String text) {
        final e = Encrypter(AES(_key, mode: AESMode.cbc));
        final decryptedData = e.decrypt(Encrypted.fromBase64(text), iv: iv);
        return decryptedData;
      }
    }

Sometimes, "/" char coming in encrypted ID, which causes 404 and 405 errors on POST request. Because "/" is HTML routing character.

My POST code is:

///Adds an user item to database via decoding / encoding the JSON value.
///[name] is name, [surname] is surname, [uid] is user id, [type] is user role, [debt] is user debt, [paucode] is pay code.
  static Future<bool> addUserToDatabase(String name, String surname, String uid,
      double debt, String paycode, int type) async {
    try {
      if (name != null &&
          surname != null &&
          uid != null &&
          debt != null &&
          paycode != null &&
          type != null) {
        var addingUser = User(name.toLowerCase(), surname.toLowerCase(),
            Security.encryptMyData(uid), type, debt, paycode);

        print('This user will be added:\n------\n$addingUser\n-----------\n');

        var uri = Uri.https('localhost:5001',
            'User/username=${addingUser.userName}&surname=${addingUser.userSurname}&id=${addingUser.personID}&debt=${addingUser.userDebt}&type=${addingUser.type}&paycode=${addingUser.payCode}');
        print('The URI: $uri');
        var request = await http.post(uri);
        print(
            'The response:\n----\n- ${request.body}\n Status Code: ${request.statusCode}\n----\n');
        if (request.statusCode == 201 || request.statusCode == 200) {
          // If the server did return a 201 Created response,
          // then return value.
          return true;
        } else {
          // If the server did not return a 200 OK response,
          // then throw an exception.
          throw Exception(
              'Failed to add user. Status Code: ${request.statusCode}');
        }
      }
      return false;
    } catch (e) {
      print('An error occurred - $e');
      return false;
    }
  }

How I escaping from "/" character in Dart encryption ? I don't want this character in the encrypted string. Thanks.

Ad

Answer

encryptMyData() Base64 encodes the data. The Base64 alphabet contains alphanumeric characters and the characters /, + and = (padding), where the last three have a special meaning and are therefore reserved in the context of URIs.

A simple way to mask these characters would be to URL encode the Base64 encoded strings with Uri.encodeComponent(). Accordingly, URL decoding with Uri.decodeComponent() must be performed before Base64 decoding:

var base64Data = 'EBES/+7dzA==';
var urlEnc = Uri.encodeComponent(base64Data);
print(urlEnc); // EBES%2F%2B7dzA%3D%3D

// Apply in URL

var urlDec = Uri.decodeComponent(urlEnc);
print(urlDec); // EBES/+7dzA==

Alternatively, Base64url can be applied instead of Base64. Base64url uses the characters _ and - instead of / and + as well as optional padding. Unlike / and +, _ and - are not reserved for URIs.

Base64url is supported in Dart by base64Url.encode(). The padding is applied, but can be removed explicitly (e.g. with replaceAll('=','')). Decoding is possible with base64Url.decode() (after the padding has been added). Alternatively, base64Url.normalize() can be used to convert to Base64 (which automatically adds the padding) and base64.decode() can be applied for Base64 decoding:

var b64urlEnc = base64Url.encode([16, 17, 18, 255, 238, 221, 204]);// [0x10, 0x11, 0x12, 0xff, 0xee, 0xdd, 0xcc]
print(b64urlEnc); // EBES_-7dzA==
var b64urlEncNoPadding = b64urlEnc.replaceAll('=','');
print(b64urlEncNoPadding); // EBES_-7dzA

// Apply in URL

var base64Enc = base64Url.normalize(b64urlEncNoPadding);
print(base64Enc); // EBES/+7dzA==
var base64Dec = base64.decode(base64Enc);
print(base64Dec); // [16, 17, 18, 255, 238, 221, 204]

Optionally, for already Base64 encoded data, the characters / and + can be replaced by _ and - and the padding (=) can be removed.

Ad
source: stackoverflow.com
Ad