在java中发送rc4加密的api调用

时间:2013-08-16 05:36:22

标签: java php encryption

我正在尝试使用以下步骤在java中进行api调用:

  1. json encode
  2. RC4加密
  3. base64编码
  4. 我目前在php中使用相同的系统并且其工作正常:

    $enc_request = base64_encode(openssl_encrypt(json_encode($request_params), "rc4", $this->_app_key));
    

    但是当我在java中使用相同的系统时,结果并不像预期的那样。这是我的代码:

    //json encoding
    JSONObject obj = new JSONObject();
    obj.put("email", username);
    obj.put("password", password);
    obj.put("action", "login");
    
    //function to encode base64
    private String getBase64Encoded(String encryptedJsonString)
    {
        byte[] encoded = Base64.encodeBase64(encryptedJsonString.getBytes());
    
        String encodedString = new String(encoded);
    
        return encodedString;
    }
    
    //function to encrypt in RC4
    private String getRC4EncryptedString2(String string, String key) throws Exception
    {
        Cipher cipher = Cipher.getInstance("RC4");
        SecretKeySpec rc4Key = new SecretKeySpec(key.getBytes(), "RC4");
        cipher.init(Cipher.ENCRYPT_MODE, rc4Key);
    
        byte[] cipherText = cipher.update(string.getBytes());
    
        return new String(cipherText);
    }
    

    我能够识别出RC4加密的问题,这个问题没有返回与php版本相同的结果。

    我已经和他争斗了2天了。我希望我没有错过任何愚蠢的事情,因为这应该是直截了当的。

    由于

2 个答案:

答案 0 :(得分:1)

您应该使用byte[]而不是String来保存中间字节数组值。 String用于文本,而不是原始数据,并将尝试使用系统的默认字符集(至少单参数String构造函数)将字节解码为字符数据。与String.getBytes()相同。

直接从cipherText返回getRC4EncryptedString2(),然后直接将其传递给getBase64Encoded()。这些编码器在字节数组上运行是有原因的,原因是,因此您可以通过在其间应用字符编码来使数据混乱。

您传递给getRC4EncryptedString2()的密钥也是如此。至少使用String.getBytes("ISO-8859-1")或其他东西(假设你的密钥实际上是文本而不是另一个乱码字节数组)。无参数版本的getBytes()返回使用系统默认字符集编码的文本,但不保证是您想要的。

这也适用于您从base 64编码器返回的String。我不知道您使用的是哪种base 64编码器,但请确保为String构造函数指定字符集。很可能你会很好,纯粹是巧合,但你应该总是在转换为/ String和原始字节时指定一个字符集。当然,假设您的base 64编码器返回文本,而不是0-63范围内的字节。

这里的一般要点是,您不能只从String来回转换为byte[]String用于文本,而byte[]表示取决于字符编码。

答案 1 :(得分:0)

我可以使用以下代码实现这一目标。希望这会有所帮助!

import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

import org.apache.commons.codec.DecoderException;
import org.bouncycastle.util.encoders.Hex;
import org.json.JSONException;
import org.json.JSONObject;

public class RC4Algo {

    public static void main(String args[])throws IOException, NoSuchAlgorithmException, DecoderException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, JSONException
    {
        decryptRC4();
    }

    static String decryptRC4() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, JSONException{

        //byte[] plainBytes = "testString".getBytes();

        //json encoding
        JSONObject obj = new JSONObject();
        obj.put("email", "username");
        obj.put("password", "password");
        obj.put("action", "login");

        byte [] plainBytes = obj.toString().getBytes();

        String hashedKey = hashedData("thisismysecretkey");

        //Generate a new key using KeyGenerator
        /*KeyGenerator rc4KeyGenerator = KeyGenerator.getInstance("RC4");
        SecretKey key = rc4KeyGenerator.generateKey();*/

        Key key = new SecretKeySpec(Hex.decode(hashedKey), "RC4");

        // Create Cipher instance and initialize it to encrytion mode
        Cipher cipher = Cipher.getInstance("RC4");  // Transformation of the algorithm
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] cipherBytes = cipher.doFinal(plainBytes);

        String encoded = encodeBase64(cipherBytes);

        String decoded = decodeBase64(encoded);

        // Reinitialize the Cipher to decryption mode
        cipher.init(Cipher.DECRYPT_MODE,key, cipher.getParameters());
        byte[] plainBytesDecrypted = cipher.doFinal(Hex.decode(decoded));

        System.out.println("Decrypted Data : "+new String(plainBytesDecrypted));
        return new String(plainBytesDecrypted);
    }

    static String decodeBase64(String encodedData){
        byte[] b = Base64.getDecoder().decode(encodedData);
        String decodedData = DatatypeConverter.printHexBinary(b);
        return decodedData;
    }

    static String encodeBase64(byte[] data){
        byte[] b = Base64.getEncoder().encode(data);
        String encodedData = new String(b);
        /*String encodedData = DatatypeConverter.printHexBinary(b);*/
        return encodedData;
    }

    static String hashedData(String key) throws NoSuchAlgorithmException{
        String password = key;

        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(password.getBytes());

        byte byteData[] = md.digest();

        //convert the byte to hex format method 1
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < byteData.length; i++) {
         sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
        }

        //convert the byte to hex format method 2
        StringBuffer hexString = new StringBuffer();
        for (int i=0;i<byteData.length;i++) {
            String hex=Integer.toHexString(0xff & byteData[i]);
            if(hex.length()==1) hexString.append('0');
            hexString.append(hex);
        }
        return hexString.toString();
    }

    }

输出:

enter image description here