I tried to encrypt the same value on both sides to see whether I get
the same encrypted bytes. This also did not work. I use Sun JCE1.2 on
Java side with algorithm "DES/EBC/PKCS5Padding" On C++ side, I use
CryptEncrypt function with CALG_DES symmetric key which I import into
the CSP using a private key of exponent one. (Thus I know I have the
same keys. It is; 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 - 8 bytes of
0x01)
Is there anybody that could help me with this problem?
Thanks in advance.
What Windows platform are you using? Also if you post your code it would be
easier to find the problem.
"Omer Hasret" <has...@uekae.tubitak.gov.tr> wrote in message
news:b58a1c1e.01112...@posting.google.com...
HCRYPTKEY hPubPrivKey = 0;
HCRYPTKEY hSessionKey = 0;
LPBYTE pbKeyMaterial = NULL;
DWORD dwKeyMaterial ;
int n;
HCRYPTPROV hCryptProv;
if(CryptAcquireContext(
&hCryptProv, // Handle to the CSP
"OMER", // Container name
MS_ENHANCED_PROV, // Provider name
PROV_RSA_FULL, // Provider type
0)) // Flag values
{
printf("A crypto context with the %s key container \n", "OMER");
printf("has been acquired.\n\n");
}
// Create Exponent of One private key
if (!(CreatePrivateExponentOneKey(MS_ENHANCED_PROV, PROV_RSA_FULL,
"OMER", AT_KEYEXCHANGE,
&hCryptProv, &hPubPrivKey)))
{
printf("CreatePrivateExponentOneKey failed with %x\n",
GetLastError());
}
// Here I am setting the session key - 8 bytes of 0x43 (the Char 'C')
pbKeyMaterial = (LPBYTE)LocalAlloc(LPTR, 64/8);
for (n = 0; n < 64/8; n++) pbKeyMaterial[n] = 0x43;
dwKeyMaterial = 64/8;
if (!ImportPlainSessionBlob(hCryptProv, hPubPrivKey, CALG_DES,
pbKeyMaterial, dwKeyMaterial, &hSessionKey))
{
printf("ImportPlainSessionBlob failed with %x\n",
GetLastError());
}
LocalFree(pbKeyMaterial);
pbKeyMaterial = NULL;
//CryptGenKey(hCryptProv,CALG_RC2,NULL,&hSessionKey);
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Here I export the session key I imported above just for checking.
// I use a private key of exponent one.
if (!(ExportPlainSessionBlob(hPubPrivKey, hSessionKey,
&pbKeyMaterial , &dwKeyMaterial
)))
{
printf("ExportPlainSessionBlob failed with %x\n",
GetLastError());
}
// Print Key material
printf("3DES session key:\n");
for (n = 0; n < dwKeyMaterial; n++)
{
if (n%8 == 0) printf(" ");
printf("%02x", pbKeyMaterial[n]);
}
printf("\n");
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//--------------------------------------------------------------------
DWORD dwCount=8;
BYTE *input;
input = (BYTE*)malloc(8);
for (n=0;n<dwCount;n++)
input[n]=0x43;
// Encrypt data.
if(!CryptEncrypt(
hSessionKey,
0,
1,
0,
NULL,
&dwCount,
8))
{
printf("Error during CryptEncrypt. \n");
}
input = (BYTE *)malloc(dwCount);
if(!CryptEncrypt(
hSessionKey,
0,
1,
0,
input,
&dwCount,
24))
{
printf("Error during CryptEncrypt2. \n");
}
for (n=0;n<dwCount;n++)
printf(" %02x",input[n]);
printf("\n");
//--------------------------------------------------------------------
// Everything goes fine however what I get from C++ is different than
what I
// get from Java Sun JCE.
//--------------------------------------------------------------------
//--------------------------------------------------------------------
Thanks for your reply.
Omer.
PS: For the java code, it is a simple
Cipher cp = Cipher.getInstance("DES/ECB/PKCS5Padding");
cp.doFinal()
"Vitaly Korovinsky" <nospam....@sympatico.ca> wrote in message news:<Nb8N7.14965$Vm5.2...@news20.bellglobal.com>...
In the Java code you are (correctly, I think) using DES, which is
a block cipher and uses a symmetric key (or "secret key"), i.e.
both the sender and the receiver use the same key.
In the C code it looks to me as though you are using RSA encryption,
where there is a key pair (a private key and corresponding public key).
In other words, I think your Java code is correct and your C code is wrong --
you need to find the part of the C API that deals with symmetric ciphers like
DES and use that instead.
Thomas Maslen
tma...@wedgetail.com
Here is a sample where java code and C code produce identical results. I
could not get the first call to CryptEncrypt working. The one which supposed
to return the size of encrypted data block. I bet your code wasn't working
for the same reason. If anyone figures out how to do it let me know.
// ------------------------------
JAVA -----------------------------------------------
public static void main(String[] args) {
try {
// Add security provider
Security.addProvider( new com.sun.crypto.provider.SunJCE() );
// hash the password
MessageDigest md = MessageDigest.getInstance("MD5");
md.update("password".getBytes());
// create key
DESKeySpec key = new DESKeySpec (md.digest());
SecretKeySpec DESKey = new SecretKeySpec (key.getKey(), "DES");
// create cipher
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, DESKey);
// encrypt info
byte[] cipherEncryptText = cipher.doFinal("Hello World!".getBytes());
// print encrypted message
for (int i=0; i<cipherEncryptText.length; ++i)
{
System.out.print(Integer.toHexString(cipherEncryptText[i]));
System.out.print(" ");
}
}
catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
// ------------------------------ C CRYPTO
API -----------------------------------------------
void main()
{
BOOL bResult=false;
HCRYPTPROV hProv=0;
// Attempt to acquire a handle to the default key container.
bResult = CryptAcquireContext(
&hProv, // Variable to hold returned handle.
NULL, // Use default key container.
MS_ENHANCED_PROV_A, // Use enhanced CSP.
PROV_RSA_FULL, // Type of provider to acquire.
0); // No special action.
// Create hash object
HCRYPTHASH hHash=0;
bResult=CryptCreateHash(
hProv, // CSP handle
CALG_MD5, // hash algorith ID
0, // Key not used
0, // flags not used
&hHash // handle to the hash object
);
// hash password
char sPassword[]="password";
bResult=CryptHashData(
hHash, // hash handle
(unsigned char*) sPassword,// pointer to the data buffer
strlen(sPassword), // data length
0 // flags not used
);
// Create key from hash
HCRYPTKEY hKey=0;
bResult=CryptDeriveKey(
hProv, // CSP handle
CALG_DES, // algorithm id
hHash, // hash object
0, // flags are not used
&hKey // key handle
);
// set encryption mode to ECB
DWORD dwParam=CRYPT_MODE_ECB;
bResult=CryptSetKeyParam(
hKey, // key handle
KP_MODE, // set key mode flag
(unsigned char*) &dwParam, // new mode value
0 // flags not used
);
// set padding mode to PKCS5
dwParam=PKCS5_PADDING;
bResult=CryptSetKeyParam(
hKey, // key handle
KP_PADDING, // set key mode flag
(unsigned char*) &dwParam, // new mode value
0 // flags not used
);
// create big buffer
char sSrcData[]="Hello World!"; // source data
DWORD dwDataLen=strlen(sSrcData); // size of the source data
DWORD dwSize=dwDataLen; // size of the encrypted data
/* THIS DOESN'T WORK.
1. Does not update dwSize value
2. Affects (screws up) encrypted data
3. Am I using it the wrong way?????
// Get the size of the encrypted block
bResult = CryptEncrypt(
hKey, // Key obtained earlier
0, // No hashing of data
FALSE, // Final or only buffer of data
0, // Must be zero
0, // No data this time
&dwSize, // length of the source data
0 // Size of block
);
// allocate and intialize the buffer
char* sDestData=new char[dwSize];
strcpy(sDestData, sSrcData);
*/
// Allocate big buffer
dwSize=200;
char* sDestData=new char[dwSize];
strcpy(sDestData, sSrcData);
// Now encrypt the data
bResult = CryptEncrypt(
hKey, // Key obtained earlier
0, // No hashing of data
TRUE, // Final or only buffer of data
0, // Must be zero
(unsigned char*)sDestData, // Data buffer
&dwDataLen, // Size of data
dwSize // Size of block
);
// print out encrypted data
for (unsigned int i=0; i<dwDataLen; ++i)
{
printf("%2x ",unsigned char(sDestData[i]));
}
// cleanup
if(hHash != 0) CryptDestroyHash(hHash);
if(hKey != 0) CryptDestroyKey(hKey);
if(hProv != 0) CryptReleaseContext(hProv,0);
}
Best regards,
Vitaly Korovinsky
Brainbench MVP for Internet Security
http://www.brainbench.com