[英]how to decrypt image received from server
就我而言,我已經生成了RSA密鑰對和AES密鑰。 我使用AES密鑰加密了圖像,然后使用RSA公鑰進一步加密了圖像。 要解密圖像,我將必須使用RSA私鑰來解密AES密鑰,而AES密鑰又將用於解密圖像。 問題是,如果僅是一段代碼,我知道該怎么做,而現在我只有2條代碼,所以我不確定如何解密從服務器下載到客戶端的圖像。
以下代碼將允許客戶端從服務器下載圖像,但是由於圖像已加密,因此無法打開。
服務器.java
public class Server {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(15123);
Socket socket = null;
String path = "C:\\Users\\john\\Documents\\Applied Cryptography\\Assignment 2";
//start of AES
//Generate AES Key
int sizeofkey = 128;
KeyGenerator kg = KeyGenerator.getInstance("AES");
//initialize with sizeofkey(aes)
kg.init(sizeofkey);
Key mykey = kg.generateKey();
System.out.println("AES Key Generated");
//create cipher object & initialize with generated key(aes)
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, mykey);
//create RSA keypair(rsa)
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
//generate RSA keypair(rsa)
KeyPair keyPair = keyPairGenerator.genKeyPair();
//split keys(rsa) and store in file
PublicKey pub = keyPair.getPublic();
PrivateKey priv = keyPair.getPrivate();
X509EncodedKeySpec pubkey = new X509EncodedKeySpec(pub.getEncoded());
FileOutputStream fos = new FileOutputStream(path + "/public.key");
fos.write(pubkey.getEncoded());
fos.close();
//Initialise the RSA cipher with PUBLIC key
Cipher rsacipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
rsacipher.init(Cipher.ENCRYPT_MODE, pub);
//Get bytes for AES key & encrypt bytes of AES key
byte[] encryptedKey = mykey.getEncoded();
byte[] cipherkey = rsacipher.doFinal(encryptedKey);
System.out.println("AES key Encrypted");
while (true) {
socket = serverSocket.accept();
System.out.println("Accepted connection : " + socket.getRemoteSocketAddress().toString() + " <-> /127.0.0.1:15123");
OutputStream sos = socket.getOutputStream();
// get the image from a webcam
URL myimage = new URL("http://183.76.13.58:80/SnapshotJPEG?Resolution=640x480");
//Picture in byte array format
byte[] plainpic = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream is = null;
try {
//in = new DataInputStream(myimage.openStream());
is = myimage.openStream();
byte[] byteChunk = new byte[4096];
int n;
while ((n = is.read(byteChunk)) > 0) {
baos.write(byteChunk, 0, n);
}
//Picture in byte array format
plainpic = baos.toByteArray();
System.out.println(plainpic);
} catch (Exception ee) {
System.out.println("Check internet connection please");
socket.close();
return;
}
byte[] cipherpic = cipher.doFinal(plainpic);
DateFormat dateFormat = new SimpleDateFormat("yy/MM/dd HH:mm:ss");
Date date = new Date();
System.out.println("Sending image " + dateFormat.format(date));
sos.write(cipherpic);
System.out.println("-------------- Done ----------");
is.close();
sos.flush();
sos.close();
socket.close();
}
}
}
客戶端.java
public class Client {
public static void main(String[] args) throws IOException {
String fname = "image.jpg";
String path = "C:\\Users\\john\\Documents\\Applied Cryptography\\Assignment 2";
File pubkeyfile = new File(path + "/public.key");
FileInputStream fis = new FileInputStream(path + "/public.key");
byte[] encodedPubKey = new byte[(int) pubkeyfile.length()];
fis.close();
Socket socket = new Socket("127.0.0.1", 15123);
InputStream is = null;
byte[] isbytearray = null;
try {
is = socket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] byteChunk = new byte[40000];
int n;
while ((n = is.read(byteChunk)) > 0) {
baos.write(byteChunk, 0, n);
}
isbytearray = baos.toByteArray();
//decrypt encrypted byte[], convert decrypted byte[] to bytes
//how to decrypt?
} catch (Exception ee) {
System.out.println("Check connection please");
socket.close();
return;
}
FileOutputStream fos = new FileOutputStream(fname);
try {
//write converted bytes to file to display picture
fos.write(isbytearray); //this is the encrypted image,not the decrypted one
} catch (EOFException ee) {
System.out.println("File transfer complete");
is.close();
}
fos.flush();
fos.close();
socket.close();
public static String asHex ( byte buf[]){
//Obtain a StringBuffer object
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10)
strbuf.append("0");
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
// Return result string in Hexadecimal format
return strbuf.toString();
}
}
}
您完全忽略了IV(初始化載體)。
從理論上講,您始終使用一個新密鑰,因此它可能是靜態的,但是使用RSA加密時,它是隨機生成的,因此您必須保留IV(通常將IV放在密文之前)並在解密時使用該值。 即使在您指出iv可能是靜態的情況下,也請養成正確使用它的習慣(隨機)iv)
使用AES和顯式IV加密
SecureRandom rnd = new SecureRandom();
byte[] iv = new byte[SYMMETRIC_BLOCK_SIZE / 8];
rnd.nextBytes(iv);
encryptionParams.setIv(iv);
IvParameterSpec ivParamSpec = new
IvParameterSpec(iv);
SecretKey symmetricKey = new
SecretKeySpec(encryptionParams.getKey(), SYMMETRIC_KEY_ALG);
Cipher cipher =
Cipher.getInstance(SYMMETRIC_CIPHER_NAME);
cipher.init(Cipher.ENCRYPT_MODE, symmetricKey, ivParamSpec);
然后解密
// encryptionParams is an object I use to pass ciphertext, iv and mac
IvParameterSpec ivParamSpec = new
IvParameterSpec(encryptionParams.getIv());
// you can read iv as part of the passed data
SecretKey symmetricKey = new
SecretKeySpec(encryptionParams.getKey(), SYMMETRIC_KEY_ALG);
Cipher cipher =
Cipher.getInstance(SYMMETRIC_CIPHER_NAME);
cipher.init(Cipher.DECRYPT_MODE, symmetricKey, ivParamSpec);
對於工作和適當的示例,您可以閱讀例如https://gusto77.wordpress.com/2017/10/30/encryption-reference-project/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.