Archive for October, 2008

IE, SSL and “Nonsecure Items”

Monday, October 6th, 2008

You finally figured out the cert chain for the self-signed certs and got your server configured. You browse to your page using HTTPS with Firefox, looks good! Lock icon and all.

Then you try in IE and get the “This page has both secure and nonsecure items.”

Learn it. Love it. Live it.

Note that, while the various JavaScript frameworks (YUI, etc.) have had issues with this, it was my own dunderheadedness that tripped me up.

Apache and mod_auth_sspi

Monday, October 6th, 2008

More of placeholder to hold my thoughts than a real howto…here’s some sample config:

<IfModule mod_alias.c>
    Alias /path "c:/svn/trunk/path"
    <Directory "c:/svn/trunk/path">
        Order allow,deny
 	Allow from all

        AuthName "My Windows Authentication"
        AuthType SSPI
        SSPIAuth On
        SSPIAuthoritative On
        SSPIDomain domain.to.authenticate.against
        SSPIOmitDomain On
        SSPIOfferBasic On
        SSPIBasicPreferred Off
        SSPIUsernameCase lower

        require valid-user
     </Directory>
</IfModule>

Rijndael-256 (AES256) and C# and PHP

Saturday, October 4th, 2008

I needed to be able to encrypt/decrypt in PHP and decrypt in C# using the same key. So I put the key and initialization vector in a XML file and use it in the PHP and C#.

A few quick notes:

  • PHP’s MD5 implementation returns the hash in a 32 character string. C#’s MD5 implementation produces a 16 byte binary array. This is why I convert the byte array to a string in C#.
  • The code assumes you are storing the encrypted data in a base 64 encoded string.
  $td = mcrypt_module_open('rijndael-256', '', 'cbc', '');
  if ($td !== FALSE)
  {
    $expected_key_size = mcrypt_enc_get_key_size($td);
    $key = substr(md5($key), 0, $expected_key_size);

    $rc = mcrypt_generic_init($td, $key, $iv);
  }

So now $td is an object that can encrypt/decrypt, like this:

Encrypt:

base64_encode(mcrypt_generic($td, $plaintext));

Decrypt:

mdecrypt_generic($td, base64_decode($str));

Now for the C#.

Initialization:

byte[] keyBytes = Encoding.ASCII.GetBytes(key.value);
byte[] hash = MD5.Create().ComputeHash(keyBytes);
string ret = "";
foreach (byte a in hash)
{
    if (a < 16)
        ret += "0" + a.ToString("x");
    else
        ret += a.ToString("x");
}

byte[] ivBytes = Convert.FromBase64String(key.iv);

r = Rijndael.Create();

r.Padding = PaddingMode.Zeros;
r.BlockSize = 256;
r.Key = Encoding.ASCII.GetBytes(ret);
r.IV = ivBytes;

Encrypt/decrypt:

public string decrypt(string str)
{
    byte[] encryptedBytes = Convert.FromBase64String(str);
    byte[] decryptedBytes = transformBytes(
        r.CreateDecryptor(), encryptedBytes);

    string plaintext = Encoding.ASCII.GetString(decryptedBytes);
    int idx = plaintext.IndexOf("");
    if (idx > -1)
        plaintext = plaintext.Substring(0, idx);

    return plaintext;
}

public string encrypt(string plaintext)
{
    byte[] plainBytes = Encoding.ASCII.GetBytes(plaintext);
    byte[] encryptedBytes = transformBytes(
        r.CreateEncryptor(), plainBytes);

    return Convert.ToBase64String(encryptedBytes);
}

private byte[] transformBytes(ICryptoTransform transform,
    byte[] plainBytes)
{
    MemoryStream memStream = new MemoryStream();
    CryptoStream cryptStream =
        new CryptoStream(memStream, transform,
        CryptoStreamMode.Write);
    cryptStream.Write(plainBytes, 0, plainBytes.Length);
    cryptStream.Close();
    byte[] encryptedBytes = memStream.ToArray();
    memStream.Close();

    return encryptedBytes;
}