1

我正在尝试像这样在客户端加密一个字符串

public static void main(String[] args) throws Exception {
    Client client = Client.create();
    Form form = new Form();
    String en = getRsaEcryptedData();
    form.add("params", getRsaEcryptedData());
    WebResource webResource = client.resource("http://localhost:8080/Server/request/data");
    ClientResponse response = webResource.type(MediaType.APPLICATION_OCTET_STREAM).post(ClientResponse.class, form);
    Reader r = new InputStreamReader(response.getEntityInputStream());  
    StringWriter sw = new StringWriter();  
    char[] buffer = new char[1024];  
    for (int n; (n = r.read(buffer)) != -1; )  
        sw.write(buffer, 0, n);  
    String str = sw.toString();  
    System.out.println(str);


}

private static String getRsaEcryptedData() {
    AsymetricKeyCryptography ac = new AsymetricKeyCryptography();
    String source = "helloworld";
    return new String(ac.encrypt(source));
}

我正在尝试像这样在服务器端解密相同的内容。我正在使用 jersey 来公开 Web 服务。

@POST
@Path("data")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
public String getMsg(@FormParam("params") String params) {
    System.out.println("params--> "+params);
    return getRsaDecryptedData(params);
}

private static String getRsaDecryptedData(String data) {
    AsymetricKeyCryptography ac = new AsymetricKeyCryptography();
    return new String(ac.decrypt(data.getBytes()));
}

AysmetricKeyCryptography 类如下所示

public class AsymetricKeyCryptography {


public AsymetricKeyCryptography() {
    super();
    if (!areKeysPresent()) {
        generateKey();
    }
}



/**
 * Generate key which contains a pair of private and public key using 1024
 * bytes. Store the set of keys in Prvate.key and Public.key files.
 * 
 * @throws NoSuchAlgorithmException
 * @throws IOException
 * @throws FileNotFoundException
 */
public static void generateKey() {
    try {
        final KeyPairGenerator keyGen = KeyPairGenerator.getInstance(Constants.ALGORITHM);
        keyGen.initialize(1024);
        final KeyPair key = keyGen.generateKeyPair();

        File privateKeyFile = new File(Constants.PRIVATE_KEY_FILE);
        File publicKeyFile = new File(Constants.PUBLIC_KEY_FILE);

        //create the public and private key files
        createPUBPRIVFiles(privateKeyFile,publicKeyFile);

        // Saving the Public key in a file
        saveKey(publicKeyFile,key,"public");
        // Saving the Private key in a file
        saveKey(privateKeyFile,key,"private");

    } catch (Exception e) {
        e.printStackTrace();
    }

}



/** saves the keys in proper files
 * @param keyFile
 * @param key
 * @param pub_priv_flag
 */
private static void saveKey(File keyFile, KeyPair key, String pub_priv_flag) {
    try {
        ObjectOutputStream keyOS = new ObjectOutputStream(new FileOutputStream(keyFile));
        if(pub_priv_flag.equalsIgnoreCase("public")){
            keyOS.writeObject(key.getPublic());
        } else if(pub_priv_flag.equalsIgnoreCase("private")){
            keyOS.writeObject(key.getPrivate());
        }
        keyOS.close();
    }catch (Exception e) {
        e.printStackTrace();
    }
}



/**creates the public and private key files
 * @param privateKeyFile
 * @param publicKeyFile
 */
private static void createPUBPRIVFiles(File privateKeyFile, File publicKeyFile) {
    try {
        if (privateKeyFile.getParentFile() != null)
            privateKeyFile.getParentFile().mkdirs();
        privateKeyFile.createNewFile();
        if (publicKeyFile.getParentFile() != null)
            publicKeyFile.getParentFile().mkdirs();
        publicKeyFile.createNewFile();
    } catch (Exception e) {
        e.printStackTrace();
    }

}

/**
 * The method checks if the pair of public and private key has been generated.
 * 
 * @return flag indicating if the pair of keys were generated.
 */
public static boolean areKeysPresent() {
    File privateKey = new File(Constants.PRIVATE_KEY_FILE);
    File publicKey = new File(Constants.PUBLIC_KEY_FILE);
    if (privateKey.exists() && publicKey.exists()) {
        return true;
    }
    return false;
}

/**
 * Encrypt the plain text using public key.
 * 
 * @param text
 * @param key
 */
public static byte[] encrypt(String text) {
    byte[] cipherText = null;
    try {

        ObjectInputStream inputStream = null;

        // Encrypt the string using the public key
        inputStream = new ObjectInputStream(new FileInputStream(Constants.PUBLIC_KEY_FILE));
        final PublicKey key = (PublicKey) inputStream.readObject();


        // get an RSA cipher object and print the provider
        final Cipher cipher = Cipher.getInstance(Constants.ALGORITHM);


        // encrypt the plain text using the public key
        cipher.init(Cipher.ENCRYPT_MODE, key);
        cipherText = cipher.doFinal(text.getBytes());
    } catch (Exception e) {
        e.printStackTrace();
    }
    return cipherText;
}

/**
 * Decrypt text using private key.
 * @param text
 * @param key
 */
public static String decrypt(byte[] text) {
    byte[] dectyptedText = null;
    try {
        System.out.println("loading private key : "+Constants.PRIVATE_KEY_FILE);
        ObjectInputStream inputStream = null;
        inputStream = new ObjectInputStream(new FileInputStream(Constants.PRIVATE_KEY_FILE));
        final PrivateKey key = (PrivateKey) inputStream.readObject();
        final Cipher cipher = Cipher.getInstance(Constants.ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key);
        dectyptedText = cipher.doFinal(text);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return new String(dectyptedText);
}


}

当我在 AsymetricKeyCryptography 类中运行 main 方法时,我得到了正确的结果,但是当我通过发送加密字符串调用 Web 服务时,它会引发异常:

javax.crypto.IllegalBlockSizeException: Data must not be longer than 128 bytes
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:337)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:382)
at javax.crypto.Cipher.doFinal(Cipher.java:1922)
at AsymetricKeyCryptography.decrypt(AsymetricKeyCryptography.java:161)
at SecureService.getRsaDecryptedData(SecureService.java:34)
at SecureService.getMsg(SecureService.java:29)

我不明白我哪里出错了

4

1 回答 1

2

我怀疑当您通过 StringWriter 汇集数据并将其作为 Jersey 中的字符串读回时,您的数据会损坏。它应该一直保持一个字节数组。尝试通过 ByteArrayOutputStream 编写它并将其作为 byte[] 或 InputStream 绑定到 Jersey 方法。

于 2013-09-06T00:08:14.117 回答