【Salesforce】Input length must be multiple of 16 when decrypting with padded cipher

【Salesforce】Input length must be multiple of 16 when decrypting with padded cipher

【Salesforce】Input length must be multiple of 16 when decrypting with padded cipher

Salesforceで外部のシステムと連携する際に、URLパラメータを使用する処理がありました。

平文のままでは宜しくないということで、暗号化を行ってURLパラメータに持たせました。

こんな感じの処理を作りました。

/**
 * URLパラメータの暗号化を行う
 * 暗号化方式はAES256
 * @param plainText 暗号化対象の文字列
 */
public static String encryptUrlParam(String plainText){

    String encryptedText;
    Blob encrypted;
    Blob cipherText;
    Blob privateKey;
    Blob initializationVector;

    // 暗号化キーを設定する
    privateKey = Blob.ValueOf('暗号化キー');
    // 初期化ベクトルを設定する
    initializationVector = Blob.ValueOf('初期化ベクトル');

    // バイナリにする
    cipherText = Blob.valueOf(plainText);
    // 暗号化する
    encrypted = Crypto.encrypt('AES256', privateKey, initializationVector, cipherText);

    // 暗号化されたバイナリをBase6形式にする
    encryptedText = EncodingUtil.base64Encode(encrypted);

    return encryptedText;
}
/**
 * URLパラメータの複合化を行う
 * 暗号化方式はAES256
 */
public static String dencryptUrlParam(String encryptedText){

    String plainText;
    Blob encrypted;
    Blob cipherText;
    Blob privateKey;
    Blob initializationVector;


    // 暗号化キーを設定する
    privateKey = Blob.ValueOf('暗号化キー');
    // 初期化ベクトルを設定する
    initializationVector = Blob.ValueOf('初期化ベクトル');

    // バイナリにする
    encrypted = EncodingUtil.base64Decode(encryptedText);

    // 複合化する
    cipherText = Crypto.decrypt('AES256', privateKey, initializationVector, encrypted);
    // 文字列に直す
    plainText = cipherText.toString();

    return plainText;
}

パラメータの値をメソッドに投げるだけで暗号化し、Base64エンコードを行うという単純なものです。

開発者コンソールから試したときにはうまく動きました。

String plainText = 'あいうえお';
String encryptedText;

encryptedText = Util.encryptUrlParam(plainText);
    
system.debug('【ログ】encryptedText:' + encryptedText);     // koaJE46JobWZGRlA8SoVEQ==


plainText = Util.encryptUrlParam(plainText);

system.debug('【ログ】plainText:' + plainText);             // あいうえお

しかし、いざ実際のデータで連携してみると、複合化の際にエラーが発生しました。

Input length must be multiple of 16 when decrypting with padded cipher

パディングされた暗号化文字列を複合化する場合は、入力の長さを16の倍数にしてねってことらしいです。

複合化しようとしたデータはこちらです。

V5PDp8hVnER1 XgOO2WoMYO 3/Jy9m2sYSK3QMkH2ZDVgHRHnlv AnJlR epgS42

うーん、64文字ですから、16の倍数になっていますね。

で、色々と試したり調べたりして分かりました。

URLに表示されているパラメータと、複合化しようとしているパラメータが微妙に違うのです。

実際のURLパラメータはこんな感じです。

V5PDp8hVnER1+XgOO2WoMYO+3%2FJy9m2sYSK3QMkH2ZDVgHRHnlv+AnJlR+epgS42

「+」の文字列が空白にされていることが分かります。

URLに「+」の記号は設定してはいけないのですね。

そんなわけで、暗号化する際にURLエンコードを行って解決です。

String webSite;
String plainText;
String param;

// URLパラメータ
plainText = 'あいうえお';
// 暗号化する
param = encryptUrlParam(plainText);

// URLを作成する
webSite = 'http://subnetwork.jp';
// パラメータを設定する
webSite += '?param=' + EncodingUtil.urlEncode(param, 'utf-8');

まだまだ知識不足ですね。

No comments.

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です