0

Android アプリケーションで AES 暗号化を使用していますが、問題があります。アプリケーションで Aes_256_Cbc アルゴリズムを使用してパスワードを暗号化する必要があります。暗号化された文字列は毎回異なる必要があるため、毎回本当にランダムな iv が必要です。単語を暗号化するために必要なコードは次のとおりです。

import android.content.Context;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class Encryptor
{
Context context;
private static final String WORD = "aefbjolpigrschnx";
private static final String KEY = "kumyntbrvecwxasqertyplmqazwsxedc";
private final static String HEX = "0123456789ABCDEF";


public Encryptor(Context c)
{
    context = c;
}

public String getEncryptedPasswd()
{
    String ivHex = "";
    String encryptedHex = "";

    try 
    {
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        byte[] iv = new byte[16];
        random.nextBytes(iv);
        ivHex = toHex(iv);
        IvParameterSpec ivspec = new IvParameterSpec(iv);
        SecretKeySpec skeySpec = new SecretKeySpec(KEY.getBytes("UTF-8"), "AES");


        Cipher encryptionCipher = Cipher.getInstance("AES/CBC");
        encryptionCipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivspec);
        byte[] encryptedText = encryptionCipher.doFinal(WORD.getBytes("UTF-8"));
        encryptedHex = toHex(encryptedText);
    } 
    catch (Exception e) 
    {
    }
    return ivHex + encryptedHex;
}

public static String toHex(byte[] buf) 
{
    if (buf == null)
    {
        return "";
    }       
    StringBuffer result = new StringBuffer(2 * buf.length);
    for (int i = 0; i < buf.length; i++)
    {
            result.append(HEX.charAt((buf[i]>>4)&0x0f)).append(HEX.charAt(buf[i]&0x0f));

    }
    return result.toString();

}

私のアプリケーションは、getEncryptedPasswd()期待どおり、異なる16進出力を与えるたびに関数を数回呼び出します。次に、暗号化されたパスワードを、私のコードが C++ でなければならないサーバーに送信します。しかし、openssl を使用してパスワードを復号化しようとすると、正しい出力が得られません。誰でも私を助けることができますか?サーバーでの私のコードは次のとおりです。

#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <openssl/aes.h>

#define KEY "kumyntbrvecwxasqertyplmqazwsxedc"

using namespace std;

unsigned int hex2bin(char *ibuf, unsigned char *obuf, unsigned int ilen)
{
unsigned int i;
unsigned int j;
unsigned int by = 0;
unsigned char ch;

// process the list of characaters
for (i = 0; i < ilen; i++)
{
        ch = toupper(*ibuf++);
    // do the conversion
        if(ch >= '0' && ch <= '9')
    {
        by = (by << 4) + ch - '0';
    }    
    else if(ch >= 'A' && ch <= 'F')
    {
            by = (by << 4) + ch - 'A' + 10;
    }
        else
    {
        memcpy(obuf, "ERROR", 5);
            return 0;
        }

        // store a byte for each pair of hexadecimal digits
        if (i & 1) 
    {
            j = ((i + 1) / 2) - 1;
            obuf[j] = by & 0xff;
        }
}
return (j+1);
}

string iv_str = auth.substr(0, 16);
string enc_str = auth.substr(16);

char *iv_buf = new char [iv_str.length() + 1];
strcpy(iv_buf, iv_str.data());
char *enc_buf = new char [enc_str.length() + 1];
strcpy(enc_buf, enc_str.data());

unsigned long ilen;
unsigned char iv[16];
unsigned char enc_word[16]; // hex decrypt output
unsigned char word[16]; // decrypt output
unsigned char enc_key[] = KEY;
AES_KEY aeskeyDec;

    AES_set_decrypt_key(enc_key, 256, &aeskeyDec);

    ilen = hex2bin(enc_buf, enc_word, (int) strlen(enc_buf));
hex2bin(iv_buf, iv, (int) strlen(iv_buf));

    AES_cbc_encrypt(enc_word, word, ilen, &aeskeyDec, iv, AES_DECRYPT);
4

1 に答える 1

0

私はJavaではなくC++の人なので、あなたが必要とすることをするように見えると言う以外に、あなたのこの行にコメントすることはできません:

Cipher encryptionCipher = Cipher.getInstance("AES/CBC");

しかし念のため、Java がデフォルトで ECB モードを使用していることを確認できることに注意してください。あなたと同じように、私も Java で暗号化された一部のテキストを C++ で AES 復号化する必要がありました。何が起こっているのかを理解するのにしばらく時間がかかりました: OpenSSL を使用して Java AES 暗号化データを復号化する方法は?

于 2013-03-07T04:25:22.637 に答える