简体   繁体   English

密码学:AES / CTR解密

[英]Cryptography : AES/CTR Decryption

I have built an server and client application which is used to encrypt and decrypt on AES/CTR algorithm.The client side is built in C language and the server side is built in Java language.But,the encrypted ciphertext cant be decrypted in server and vice versa. 我已经构建了一个服务器和客户端应用程序,用于加密和解密AES / CTR算法。客户端使用C语言构建,服务器端使用Java语言构建。但是,加密的密文不能在服务器中解密。反之亦然。

Here is the code : (Client) 这是代码:(客户端)

$ Client(C) : $客户(C):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mcrypt.h>
#include <math.h>
#include <stdint.h>
#include <stdlib.h>

int encrypt(
   void* buffer,
int buffer_len, /* Because the plaintext could include null bytes*/
char* IV, 
char* key,
int key_len 
){
 MCRYPT td = mcrypt_module_open("rijndael-128", NULL, "ctr", NULL);
 int blocksize = mcrypt_enc_get_block_size(td);
 if( buffer_len % blocksize != 0 ){return 1;}
 mcrypt_generic_init(td, key, key_len, IV);
 mcrypt_generic(td, buffer, buffer_len);
 mcrypt_generic_deinit (td);
 mcrypt_module_close(td);
 return 0;
}

int decrypt(
  void* buffer,
  int buffer_len,
  char* IV, 
  char* key,
  int key_len 
){
  MCRYPT td = mcrypt_module_open("rijndael-128", NULL, "ctr", NULL);
  int blocksize = mcrypt_enc_get_block_size(td);
  if( buffer_len % blocksize != 0 ){return 1;} 
  mcrypt_generic_init(td, key, key_len, IV);
  mdecrypt_generic(td, buffer, buffer_len);
  mcrypt_generic_deinit (td);
  mcrypt_module_close(td);  
  return 0;
 }

void display(char* ciphertext, int len){
 int v;
 for (v=0; v<len; v++){
  printf("%d ", ciphertext[v]);
 }
 printf("\n");
}

int main() {
  MCRYPT td, td2;
  char * plaintext = "test text 123";
  char* IV = "AAAAAAAAAAAAAAAA";
  char *key = "0123456789abcdef";
  int keysize = 16; /* 128 bits */
  char* buffer;
  int buffer_len = 16;
  buffer = calloc(1, buffer_len);
  strncpy(buffer, plaintext, buffer_len);
  printf("==C==\n");
  printf("plain:   %s\n", plaintext);
  encrypt(buffer, buffer_len, IV, key, keysize); 
  printf("cipher:  "); display(buffer , buffer_len);
  decrypt(buffer, buffer_len, IV, key, keysize);
  printf("decrypt: %s\n", buffer);
  return 0;
  }

$ Server(Java) : $ Server(Java):

import java.security.MessageDigest; 
import java.util.Arrays;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.util.*;
import java.net.*;

public class AESEnc {
  static String IV = "AAAAAAAAAAAAAAAA";
  static String encryptionKey = "Hello World nexg";
  public static void main(String [] args) {
    try {
    InetAddress IPAddress = InetAddress.getByName("192.168.1.7");
    DatagramSocket clientSocket = new        DatagramSocket(5038,IPAddress);
    byte[] data=new byte[2048];
    DatagramPacket packet = new DatagramPacket(data, 2048);
    packet.setLength(2048); 
    System.out.println("Waiting for packet");
    clientSocket.receive(packet);
    String strMessage=new String(packet.getData(),0,packet.getLength());
    System.out.println("Recieved packet");
    System.out.println("==Java==");
    System.out.println("plain:   " + strMessage);
    String decrypted = decrypt(strMessage.getBytes(),encryptionKey);

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

  public static byte[] encrypt(String plainText, String encryptionKey) throws Exception {
    Cipher cipher = Cipher.getInstance("AES/CTR/PKCS5Padding", "SunJCE");
    SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
    cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8")));
    return cipher.doFinal(plainText.getBytes("UTF-8"));
  }

  public static String decrypt(byte[] cipherText, String encryptionKey) throws Exception{
    Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding", "SunJCE");
    SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
    cipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8")));
    return new String(cipher.doFinal(cipherText),"UTF-8");
  }
}

These are my server and client source code,Please let me know if you find an error in it. 这些是我的服务器和客户端源代码,如果您发现错误,请告诉我。

Thanks in Advance, 提前致谢,

PS : I am getting some junk characters after decrypting the messages sent from the client side.I am not getting the actual message which is encrypted. PS:我在解密客户端发送的消息后得到一些垃圾字符。我没有收到加密的实际消息。

Your client and server looks good,but there is an minor mistake in your UDP packet processing while fetching the data from the packet and decrypting it.Try to change it and i think your code will work. 您的客户端和服务器看起来不错,但是在从数据包中获取数据并对其进行解密时,UDP数据包处理存在一个小错误。尝试更改它,我认为您的代码将起作用。 :) :)

Different systems have different defaults, and any difference will munge up your decryption. 不同的系统有不同的默认值,任何差异都会破坏你的解密。 Check that everything is byte-for-byte the same. 检查一切都是逐字节的相同。 Display the hex values on both systems to check: key, nonce/IV, cyphertext bytes, plaintext bytes (not text). 显示两个系统上的十六进制值以检查:key,nonce / IV,cyphertext字节,明文字节(不是文本)。

It is probably best not to rely on any defaults, but to explicitly specify everything on both systems. 最好不要依赖任何默认值,而是明确指定两个系统上的所有内容。

A common source of error is text to byte conversions, which might affect the initial plaintext and possibly passphrase used as input. 常见的错误来源是文本到字节转换,这可能会影响初始明文和可能用作输入的密码。

Your junk characters might be whatever was sitting in the C buffer memory when you allocated it. 您的垃圾字符可能是分配时在C缓冲区内存中的任何内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM