Question

I am trying to create an RDP file on a computer programmatically. I am taking the username and password from a PROPERTIES file, and trying to use CryptProtectData() to encrypt it to a vlaid format. I then generate the string password 51:b:<encrypted password> and store it in the .RDP file.

When I look in the RDP file, I get output similar to the following: password 51:b:[B@3fd83fd8

Looking here: http://www.remkoweijnen.nl/blog/2007/10/18/how-rdp-passwords-are-encrypted/ you can see that the password is not in the correct format.

By the way, in order to do the encrypting, I am using the import: import com.sun.jna.platform.win32.Crypt32Util; to access Crypt32Util.cryptProtectData(passwordBytes) as can be seen from this code:

FileWriter fstream = new FileWriter(rdpFile);
BufferedWriter out = new BufferedWriter(fstream);
out.write("full address:s:"+remoteServerIP);
out.write("\nusername:s:"+username);
byte[] passwordBytes = password.getBytes();
out.write("\npassword 51:b:"+Crypt32Util.cryptProtectData(passwordBytes));

I'd be grateful to anyone who can help me encrypt the password correctly.

Thank you.

PS, I'm using Windows XP

EDIT: I found this info on encrypting using C/C++, and I looked in wincrypt.h but I couldnt identify anything useful: http://blogs.msdn.com/b/rds/archive/2007/01/22/vista-remote-desktop-connection-authentication-faq.aspx

Was it helpful?

Solution

By looking at your link, it seems that you're missing a step of converting the byte array (the result of applying CryptUtil to a password) into a hex-string representation:

out.write("\npassword 51:b:"+ ToHexString(Crypt32Util.cryptProtectData(passwordBytes)));

where ToHexString(byte[] barray):String can look something like this:

public static String ToHexString(byte[] bytes) {   
    StringBuilder sb = new StringBuilder();   
    Formatter formatter = new Formatter(sb);   
    for (byte b : bytes) {
        formatter.format("%02x", b);   
    }
    return sb.toString();   
}  

OTHER TIPS

   String paasword ="pwd";
    DATA_BLOB pDataIn = new DATA_BLOB(password.getBytes(Charset.forName("UTF-16LE")));
    DATA_BLOB pDataEncrypted = new DATA_BLOB();
    System.out.println(Crypt32.INSTANCE.CryptProtectData(pDataIn, "psw", 
            null, null, null, WinCrypt.CRYPTPROTECT_UI_FORBIDDEN, pDataEncrypted));
   StringBuffer epwsb = new StringBuffer();
   byte[] pwdBytes= new byte [pDataEncrypted.cbData];      
   pwdBytes=pDataEncrypted.getData();
    Formatter formatter = new Formatter(epwsb);
     for ( final byte b : pwdBytes ) {
    formatter.format("%02X", b);
         }
  System.out.println("password 51:b:"+ epwsb.toString());

Here's my working solution (you need JNA platform, to get this working):

    private static String ToHexString(byte[] bytes) {   
        StringBuilder sb = new StringBuilder();   
        Formatter formatter = new Formatter(sb);   
        for (byte b : bytes) {
            formatter.format("%02x", b);   
        }
        formatter.close();
        return sb.toString();   
    }  

    private String cryptRdpPassword(String pass) {
        try {
            return ToHexString(Crypt32Util.cryptProtectData(pass.getBytes("UTF-16LE"), null, 0, "psw", null));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return "ERROR";
        }
    }

I just found a way to solute this problem yestoday.It was wrong just because of the difference between windows(c++) and java. I can encypt the password and autofill it in the rdpfile,and login in the remote desktop without filling the password again.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top