Creating an authentication hash
POST variables
- HASH: Hash of the company
- ANNAEXEC: The generated IV, which will be used to encrypt the values of other variables
- ACTION: The action to be executed
- GENERATE_USER_HASH: Generates an authentication hash for the informed user (USER_ID)
- GENERATE_USER_HASH_FORCE_USER: Create or update an user with the values from USER_ID and USER_NAME, and generates an authentication hash
- INACTIVATE_USER: Inactivates the informed user (USER_ID)
- MESSENGER_STRUCTURE: Returns a json providing a list of departments (alias and name) and the list of channels for each department of the company
- MESSENGER_ALERT_COUNTER:
- Returns a json indicating the number of request with “Open” status that are pending a response for the user specified in the variable USER_ID or by the set of values in the variables MESSENGER_UNIQUE_DOC_TYPE and MESSENGER_UNIQUE_DOC_VALUE
- You can also filter the result by department, channel, initial date and final date using the variable MESSENGER_FILTER
- MESSENGER_REQUESTS:
- Returns a json with a collection of request for the user specified in the USER_ID variable or by the set of values in the MESSENGER_UNIQUE_DOC_TYPE and MESSENGER_UNIQUE_DOC_VALUE variables, containing the following data: Department, channel, request description, opening date, protocol, status (open/closed), a flag indicating if it is pending a response from the user, and a link to view the specific request.
- You can also filter the result by department, channel, start date, end date, status (A-open, E-closed), and pendings (S/N - pending a response from the user or not) using the variable MESSENGER_FILTER
- MESSENGER_LINK:
- Returns a json with the link to visualize the request full content of the messaging system for the user specified in the USER_ID variable or by the set of values in the MESSENGER_UNIQUE_DOC_TYPE and MESSENGER_UNIQUE_DOC_VALUE variables
- USER_ID: Corporate User ID
- USER_NAME: Corporate User name
- MESSENGER_UNIQUE_DOC_TYPE: Contains the document type for unique user identification in the messaging system. E.g.: CPF, RG, RA, etc. Must be encrypted using the generated encryption key and IV.
- MESSENGER_UNIQUE_DOC_VALUE: Contains the document value for unique user identification in the messaging system. E.g.: 715.037.620-76. Must be encrypted using the generated encryption key and IV.
- MESSENGER_FILTER: (OPTIONAL) Contains filters to be applied for the actions MESSENGER_ALERT_COUNTER and MESSENGER_REQUESTS. Must be encrypted using the generated encryption key and IV.
- The JSON format should be provided as follows:
{"DepartmentAlias": "CENTRALATEND","ChannelAlias": "ATENDINICIAL","DataIni": "01/01/2024","DataFim": "01/05/2024","Status": "A","Pendentes": "S"}
- The JSON format should be provided as follows:
- START_SERVICE: (Optional) Defines the service to be executed when opening AnnA Chat
Examples
public string Post() { string companyHash = "YOUR_COMPANY_HASH"; string encryptionKey = "YOUR_CORPORATE_USER_ENCRYPTION_KEY"; string decryptionKey = "YOUR_CORPORATE_USER_DECRYPTION_KEY"; string iv = GenerateIV();
string action = "GENERATE_USER_HASH"; // GENERATE_USER_HASH || GENERATE_USER_HASH_FORCE_USER || INACTIVATE_USER string userId = "USER_ID"; string username = "USERNAME"; string startService = "START_SERVICE";
// Only for MESSENGER actions and GENERATE_USER_HASH_FORCE_USER string uniqueDocType = "UNIQUE_DOC_TYPE"; string uniqueDocValue = "UNIQUE_DOC_VALUE";
// Only for MESSENGER_ALERT_COUNTER and MESSENGER_REQUESTS actions string messengerFilters = new { DepartmentAlias = "DEPARTMENT_ALIAS", ChannelAlias = "CHANNEL_ALIAS", DataIni = "START_DATE", // dd/MM/yyyy DataFim = "END_DATE", // dd/MM/yyyy Status = "STATUS", // A | E Pendentes = "PENDENTES" // S | N }
string url = "YOUR_ANNA_URL/aannacorporateuser.aspx";
string encryptedAction = Encrypt(action, encryptionKey, iv); string encryptedUserId = Encrypt(userId, encryptionKey, iv); string encryptedUserName = Encrypt(username, encryptionKey, iv); string encryptedStartService = Encrypt(startService, encryptionKey, iv); string encryptedUniqueDocType = Encrypt(uniqueDocType, encryptionKey, iv); string encryptedUniqueDocValue = Encrypt(uniqueDocValue, encryptionKey, iv); string encryptedMessengerFilters = Encrypt(JsonSerializer.Serialize(messengerFilters), encryptionKey, iv);
string dadosPost = "HASH=" + Uri.EscapeDataString(companyHash); dadosPost += "&ANNAEXEC=" + Uri.EscapeDataString(iv); dadosPost += "&ACTION=" + Uri.EscapeDataString(encryptedAction); dadosPost += "&USER_ID=" + Uri.EscapeUriString(encryptedUserId); dadosPost += "&USER_NAME=" + Uri.EscapeUriString(encryptedUserName); dadosPost += "&MESSENGER_UNIQUE_DOC_TYPE=" + Uri.EscapeUriString(encryptedUniqueDocType); dadosPost += "&MESSENGER_UNIQUE_DOC_VALUE=" + Uri.EscapeUriString(encryptedUniqueDocValue); dadosPost += "&MESSENGER_FILTER=" + Uri.EscapeDataString(encryptedMessengerFilters); dadosPost += "&START_SERVICE=" + Uri.EscapeUriString(encryptedStartService);
byte[] dados = Encoding.UTF8.GetBytes(dadosPost);
var webRequest = WebRequest.Create(url); webRequest.Method = "POST"; webRequest.ContentType = "application/x-www-form-urlencoded"; webRequest.ContentLength = dados.Length;
Stream dataStream = webRequest.GetRequestStream(); dataStream.Write(dados, 0, dados.Length); dataStream.Close();
WebResponse response = webRequest.GetResponse();
using (dataStream = response.GetResponseStream()) { StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
if (responseFromServer.Contains(iv)) { string novoIVEncriptado = responseFromServer.Substring(responseFromServer.IndexOf(iv)); novoIVEncriptado = novoIVEncriptado.Replace(iv, ""); string retornoEncriptado = responseFromServer.Substring(0, responseFromServer.IndexOf(iv));
string novoIV = Decrypt(novoIVEncriptado, encryptionKey, iv);
string retorno = Decrypt(retornoEncriptado, decryptionKey, novoIV);
response.Close(); return retorno; } else { response.Close(); return responseFromServer; } } }
public async Task<ActionResult<string>> Get() { var decryptionKey = "YOUR_DECRYPTION_KEY"; var encryptionKey = "YOUR_ENCRYPTION_KEY"; var CompanyHash = "YOUR_COMPANY_HASH";
string iv = GenerateIV();
string action = "GENERATE_USER_HASH"; // GENERATE_USER_HASH || GENERATE_USER_HASH_FORCE_USER || INACTIVATE_USER string userId = "USER_ID"; string username = "USERNAME"; string startService = "START_SERVICE";
// Only for MESSENGER actions and GENERATE_USER_HASH_FORCE_USER string uniqueDocType = "UNIQUE_DOC_TYPE"; string uniqueDocValue = "UNIQUE_DOC_VALUE";
// Only for MESSENGER_ALERT_COUNTER and MESSENGER_REQUESTS actions string messengerFilters = new { DepartmentAlias = "DEPARTMENT_ALIAS", ChannelAlias = "CHANNEL_ALIAS", DataIni = "START_DATE", // dd/MM/yyyy DataFim = "END_DATE", // dd/MM/yyyy Status = "STATUS", // A | E Pendentes = "PENDENTES" // S | N }
string encryptedAction = Encrypt(action, encryptionKey, iv); string encryptedUserId = Encrypt(userId, encryptionKey, iv); string encryptedUserName = Encrypt(username, encryptionKey, iv); string encryptedStartService = Encrypt(startService, encryptionKey, iv); string encryptedUniqueDocType = Encrypt(uniqueDocType, encryptionKey, iv); string encryptedUniqueDocValue = Encrypt(uniqueDocValue, encryptionKey, iv); string encryptedMessengerFilters = Encrypt(JsonSerializer.Serialize(messengerFilters), encryptionKey, iv);
var dadosPost = new Dictionary<string, string> { { "HASH", CompanyHash }, { "ANNAEXEC", iv }, { "ACTION", encryptedAction }, { "USER_ID", encryptedUserId }, { "USER_NAME", encryptedUserName }, { "START_SERVICE", encryptedStartService }, { "MESSENGER_UNIQUE_DOC_TYPE", encryptedUniqueDocType }, { "MESSENGER_UNIQUE_DOC_VALUE", encryptedUniqueDocValue }, { "MESSENGER_FILTER", encryptedMessengerFilters } };
var httpClient = new HttpClient();
string url = "YOUR_ANNA_URL/aannacorporateuser.aspx";
var result = await httpClient.PostAsync(url, new FormUrlEncodedContent(dadosPost)); var content = await result.Content.ReadAsStringAsync();
if (content.Contains(iv)) { string novoIVEncriptado = content.Substring(content.IndexOf(iv)); novoIVEncriptado = novoIVEncriptado.Replace(iv, ""); string retornoEncriptado = content.Substring(0, content.IndexOf(iv));
string novoIV = Decrypt(novoIVEncriptado, encryptionKey, iv);
string retorno = Decrypt(retornoEncriptado, decryptionKey, novoIV);
return Ok(retorno); }
return Ok(content); }
public static String encrypt3DES(String data, String key, String iv) { byte[] decodedIv = Base64.getDecoder().decode(iv); byte[] decodedKey = Base64.getDecoder().decode(key);
IvParameterSpec ivSpec = new IvParameterSpec(decodedIv); SecretKey secretKey = new SecretKeySpec(decodedKey, "DESede");
try { Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
byte[] plainTextBytes = data.getBytes(StandardCharsets.UTF_8); byte[] encryptedBytes = cipher.doFinal(plainTextBytes);
byte[] base64Bytes = Base64.getEncoder().encode(encryptedBytes);
return new String(base64Bytes); } catch (Exception e) { throw new RuntimeException(e); }}
public static String decrypt3DES(String data, String key, String iv) { byte[] decodedIv = Base64.getDecoder().decode(iv); byte[] decodedKey = Base64.getDecoder().decode(key);
IvParameterSpec ivSpec = new IvParameterSpec(decodedIv); SecretKey secretKey = new SecretKeySpec(decodedKey, "DESede");
byte[] encryptedBytes = Base64.getDecoder().decode(data);
try { Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); decipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
byte[] plainText = decipher.doFinal(encryptedBytes);
return new String(plainText, StandardCharsets.UTF_8); } catch (IllegalBlockSizeException | NoSuchPaddingException | NoSuchAlgorithmException | InvalidAlgorithmParameterException | InvalidKeyException | BadPaddingException e) { throw new RuntimeException(e); }}
public static String generateInitializationVector() { byte[] randomBytes = new byte[8]; new Random().nextBytes(randomBytes);
return new String(Base64.getEncoder().encode(randomBytes));}
public static String sample() { String decryptionKey = "DECRYPTION_KEY"; String encryptionKey = "ENCRYPTION_KEY"; String companyHash = "COMPANY_HASH";
String iv = generateInitializationVector();
String action = "GENERATE_USER_HASH"; // GENERATE_USER_HASH || GENERATE_USER_HASH_FORCE_USER || INACTIVATE_USER String userId = "USER_ID"; String username = "USERNAME"; String startService = "START_SERVICE";
// Only for MESSENGER actions and GENERATE_USER_HASH_FORCE_USER String uniqueDocType = "UNIQUE_DOC_TYPE"; String uniqueDocValue = "UNIQUE_DOC_VALUE";
// Only for MESSENGER_ALERT_COUNTER and MESSENGER_REQUESTS actions String messengerFilters = "{"; messengerFilters+="\"DepartmentAlias\": \"DEPARTMENT_ALIAS\","; messengerFilters+="\"ChannelAlias\": \"CHANNEL_ALIAS\","; messengerFilters+="\"DataIni\": \"START_DATE\","; // dd/MM/yyyy messengerFilters+="\"DataFim\": \"END_DATE\","; // dd/MM/yyyy messengerFilters+="\"Status\": \"STATUS\","; // A | E messengerFilters+="\"Pendentes\": \"PENDENTES\""; // S | N messengerFilters+="}";
String encryptedAction = encrypt3DES(action, encryptionKey, iv); String encryptedUserId = encrypt3DES(userId, encryptionKey, iv); String encryptedUserName = encrypt3DES(username, encryptionKey, iv); String encryptedStartService = encrypt3DES(startService, encryptionKey, iv); String encryptedUniqueDocType = encrypt3DES(uniqueDocType, encryptionKey, iv); String encryptedUniqueDocValue = encrypt3DES(uniqueDocValue, encryptionKey, iv); String encryptedMessengerFilters = encrypt3DES(messengerFilters, encryptionKey, iv);
String postBody = "HASH=" + URLEncoder.encode(companyHash, StandardCharsets.UTF_8); postBody += "&ANNAEXEC=" + URLEncoder.encode(iv, StandardCharsets.UTF_8); postBody += "&ACTION=" + URLEncoder.encode(encryptedAction, StandardCharsets.UTF_8); postBody += "&USER_ID=" + URLEncoder.encode(encryptedUserId, StandardCharsets.UTF_8); postBody += "&USER_NAME=" + URLEncoder.encode(encryptedUserName, StandardCharsets.UTF_8); postBody += "&START_SERVICE=" + URLEncoder.encode(encryptedStartService, StandardCharsets.UTF_8); postBody += "&MESSENGER_UNIQUE_DOC_TYPE=" + URLEncoder.encode(encryptedUniqueDocType, StandardCharsets.UTF_8); postBody += "&MESSENGER_UNIQUE_DOC_VALUE=" + URLEncoder.encode(encryptedUniqueDocValue, StandardCharsets.UTF_8); postBody += "&MESSENGER_FILTER=" + URLEncoder.encode(encryptedMessengerFilters, StandardCharsets.UTF_8);
try { String environmentUrl = "http://YOUR_ANNA_URL";
HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(environmentUrl + "/aannacorporateuser.aspx")) .header("Content-Type", "application/x-www-form-urlencoded") .POST(HttpRequest.BodyPublishers.ofString(postBody)) .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); String responseFromServer = response.body();
if (responseFromServer.contains(iv)) { String newEncryptedIv = responseFromServer.substring(responseFromServer.indexOf(iv)); newEncryptedIv = newEncryptedIv.replace(iv, "");
String encryptedResponse = responseFromServer.substring(0, responseFromServer.indexOf(iv));
String newIv = decrypt3DES(newEncryptedIv, encryptionKey, iv);
return decrypt3DES(encryptedResponse, decryptionKey, newIv); }
return responseFromServer;
} catch (Exception e) { throw new RuntimeException(e); }}
$DecKey = "DECKEY"; $EncKey = "ENCKEY"; $Hash = "HASH";
// Generate new IV $ivlen = openssl_cipher_iv_length('des-ede3-cbc'); $IV = base64_encode(openssl_random_pseudo_bytes(8));
$actionName = "GENERATE_USER_HASH_FORCE_USER"; $actionNameEncriptado = encrypt3DES($actionName, $EncKey, $IV);
$userId = "USER_ID"; $userIdEncriptado = encrypt3DES($userId, $EncKey, $IV);
$userName = "USER_NAME"; $userNameEncriptado = encrypt3DES($userName, $EncKey, $IV);
$dadosPost = array( 'HASH' => $Hash, 'ANNAEXEC' => $IV, 'ACTION' => $actionNameEncriptado, 'USER_ID' => $userIdEncriptado, 'USER_NAME' => $userNameEncriptado);
$url = "URL_AMBIENTE/aannacorporateuser.aspx"; $options = array( 'http' => array( 'header' => "Content-type: application/x-www-form-urlencoded\r\n", 'method' => 'POST', 'content' => http_build_query($dadosPost) ) ); $context = stream_context_create($options); $result = file_get_contents($url, false, $context);
if (str_contains($result, $IV)) { $novoIVEncriptado = substr($result, strpos($result, $IV)); $novoIVEncriptado = str_replace($IV, "", $novoIVEncriptado); $retornoEncriptado = substr($result, 0, strrpos($result, $IV));
$novoIV = decrypt3DES($novoIVEncriptado, $EncKey, $IV);
$retorno = decrypt3DES($retornoEncriptado, $DecKey, $novoIV);
echo utf8_encode($retorno); } else { echo utf8_encode($retorno); }
import requests import json from Crypto.Cipher import AES, DES3, DES from Crypto.Util.Padding import pad, unpad from Crypto.Random import get_random_bytes from base64 import b64encode, b64decode
# Encryption method def encrypt(data, enckey, iv):
enckey = b64decode(enckey) iv = b64decode(iv)
cipher = DES3.new(enckey, DES3.MODE_CBC, iv) ct_bytes = cipher.encrypt( pad(bytes(data, encoding='utf-8'), DES3.block_size)) ciphertext = b64encode(ct_bytes).decode('utf-8')
return ciphertext
# Decryption method def decrypt(data, deckey, iv): try: deckey = b64decode(deckey) iv = b64decode(iv) data = b64decode(data)
cipher = DES3.new(deckey, DES3.MODE_CBC, iv) pt = unpad(cipher.decrypt(data), DES3.block_size)
return pt.decode('utf-8')
except (ValueError, KeyError): return 'Incorrect decryption'
# Integration variables url = 'https://YOUR_ANNA_URL/aannacorporateuser.aspx' enckey = 'ENCRYPTION_KEY' deckey = 'DECRYPTION_KEY' hash = 'COMPANY_HASH' action = 'ACTION' userId = 'USER_ID' userName = 'USER_NAME' fluxo = '@FLUXO'
# Creating an IV key = get_random_bytes(8) cipher = DES.new(key, DES3.MODE_CBC) iv = b64encode(cipher.iv).decode('utf-8')
# Encrypting data actionEncypted = encrypt(action, enckey, iv) userIdEncrypted = encrypt(userId, enckey, iv) userNameEncrypted = encrypt(userName, enckey, iv) fluxoEncrypted = encrypt(fluxo, enckey, iv)
# Creating the submission structure request = { 'HASH': hash, 'ANNAEXEC': iv, 'ACTION': actionEncypted, 'USER_ID': userIdEncrypted, 'USER_NAME': userNameEncrypted, 'START_SERVICE': fluxoEncrypted }
# Making a post for AnnA response = requests.post(url, request)
# Retrieving AnnA's response response = response.text
# Separating the received IV from the AnnA response string responseEncrypted = response.split(iv)
# Decrypting the new IV newIV = decrypt(responseEncrypted[1], enckey, iv)
# Decrypting the content of the reply responseDecrypt = decrypt(responseEncrypted[0], deckey, newIV)
# Log print('\n') print(' -> Server response:\n', response) print(' -> Separating the new IV from the json:\n', responseEncrypted) print(' -> New IV: ', newIV) print(' -> Decrypted return: ', responseDecrypt) print('\n')