EXPLOREAPI

Logo Explore - Data for success

Fonctionnement général

L'authentification sur l'API EXPLORE fonctionne en temps normal selon un principe de clé d'authentification (CleClient) et de contrôle IP. Lorsque ce dernier n'est pas possible, un système de chiffrement est mis en place. Tous les webservices génériques d'EXPLORE disposent d'un équivalent dit "signé" permettant ces appels.

Seuls deux paramètres d'entrée sont nécessaires :

Le paramètre « Signature » est crypté selon une méthode de chiffrement basée sur un algorithme fiable ; AES (Advanced Encryption Standard). Pour plus d'informations sur AES, vous pouvez vous référer à la page suivante.

Votre organisation ainsi qu'EXPLORE disposent ainsi d'une clé secrète permettant l'échange confidentiel des données en cryptant et décryptant cette chaîne de paramètres. Toute personne ne possédant pas cette clé sera incapable de révéler le contenu de la signature.

L'URL obtenue par le biais du chiffrement, pour des raisons de sécurité, n'est valable que le jour même de sa génération. Il convient ainsi de rajouter la date du jour à la clé secrète comme dans l'exemple ci-dessous (en C#) :

string cleCrypteeClient = DateTime.Today.ToString("yyyyMMdd") + CleSecrete;

Le contenu du paramètre « Signature » correspond à la chaîne de paramètre « normale » du web service. Ainsi, pour le web service Amenagements de la rubrique générique Opportunites, une chaîne à cryptée a pour format « CleClient=[Votre clé client]&DateDebut=[yyyy-MM-dd]&DateFin=[yyyy-MM-dd]&MAJ=[false / true] ».

Fonctions de cryptage

La chaîne « Signature » peut être cryptée en C# grâce aux fonctions suivantes :

Générique

        
public static string EncryptExplore(string toEncrypt, string ckey)
{
    byte[] plainText = Encoding.UTF8.GetBytes(toEncrypt);

    Rfc2898DeriveBytes rfcDb = new Rfc2898DeriveBytes(ckey, Encoding.UTF8.GetBytes(ckey));
    byte[] key = rfcDb.GetBytes(16);
    byte[] iv = rfcDb.GetBytes(16);

    RijndaelManaged rijndael = new RijndaelManaged
    {
        rijndael.Mode = CipherMode.CBC;
    };
    ICryptoTransform aesEncryptor = rijndael.CreateEncryptor(key, iv);

    MemoryStream ms = new MemoryStream();
    CryptoStream cs = new CryptoStream(ms, aesEncryptor, CryptoStreamMode.Write);
    cs.Write(plainText, 0, plainText.Length);
    cs.FlushFinalBlock();

    byte[] CipherBytes = ms.ToArray();

    ms.Close();
    cs.Close();

    return Convert.ToBase64String(CipherBytes).Replace("+", "-").Replace("/", "_");
}
        
    

Cas particulier : CRM SalesForce

        
public static String encryptExplore(String toEncrypt, String ckey){
    String combinedDataAsHexclekey = '';
    String combinedDataAsHexclekeyIV = '';
    String[] clekey = ckey.split('');
    Integer i=0;
    
    for(String s : clekey) {
        if(i<=15) {
            combinedDataAsHexclekey += EncodingUtil.convertToHex(Blob.valueOf(s));
            i++;
         }
         else{
            if(i<=31){
                    combinedDataAsHexclekeyIV += EncodingUtil.convertToHex(Blob.valueOf(s));
                    i++;
                }
            }
         }

    Blob combinedDataAsBlobkey = EncodingUtil.convertFromHex(combinedDataAsHexclekey);
    Blob combinedDataAsBlobkeyIV = EncodingUtil.convertFromHex(combinedDataAsHexclekeyIV);
    blob encryptedData = Crypto.encrypt('AES128', combinedDataAsBlobkey, combinedDataAsBlobkeyIV, blob.valueOf(toEncrypt));
    String encrypt = EncodingUtil.base64Encode(encryptedData).replace('+','-').replace('/','_');

    return encrypt;
}
        
    

Cas particulier : Environnement Java

        
public static String encrypt(String toEncrypt, String cKey) throws Exception
{
    try
    {
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        PBEKeySpec pbeKeySpec = new PBEKeySpec(cKey.toCharArray(), Arrays.copyOf(cKey.getBytes("UTF-8"), cKey.getBytes("UTF-8").length), 1000, 384);
        byte[] secretKeyBytes = factory.generateSecret(pbeKeySpec).getEncoded();

        IvParameterSpec ivSpec = new IvParameterSpec(Arrays.copyOfRange(secretKeyBytes, 16, 32));
        SecretKeySpec secretKeySpec = new SecretKeySpec(Arrays.copyOfRange(secretKeyBytes, 0, 16), "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
        byte[] encrypted = cipher.doFinal(toEncrypt.getBytes("UTF-8"));

        return Base64.getEncoder().encodeToString(encrypted).replace("+", "-").replace("/", "_");
    }
    catch (Exception ex)
    {
        throw ex;
    }
}
        
    

Exemple (C#)

        
DateTime DateDebut = DateTime.Today.AddDays(-6);
DateTime DateFin = DateTime.Today;
string cleCrypteeClient = DateTime.Today.ToString("yyyyMMdd") + CleSecrete;
string parameters = string.Concat("CleClient=", CleClient, "&DateDebut=", DateDebut.ToString("yyyy-MM-dd"), "&DateFin=", DateFin.ToString("yyyy-MM-dd"));
string signature = EncryptExplore(parameters, cleCrypteeClient);
string apiUri = "https://extranet.explore.fr/ExploreAPI/api/Opportunites/MarchesPublics?CleClient=" + CleClient + "&Signature=" + signature;