Get SecurityContextToken C# Code

[Updated 1/28/05]
  – Encrypted the client public key (modulus).  Broke into 2 parts as full byte[] is too large for 1024 encrypt operation.  This encryption of public key is probably not required, but now attacker has NO information to work on.
  – Added Signature on Request.  This prevents a Man-In-Middle attack.
  – Added KeyVerifiery in Reply.  This verifies to Client that Server knows the same key.

Here is the XmlDoc and the two methods on both sides.  See Create SecurityContextTokens without X509 Certs for protocol description. 

//
// XML Document passed both ways.
//
public class SCTKeyInfo
{      // Set in:
 public byte[] Key;            // Request/Reply
 public byte[] Username;   // Request
 public byte[] Password;   // Request
 public string PublicKey;     //Request
 public string UTID;           // Reply
 public string SCTIdentifier;  // Reply
 public string SCTExpires;     // Reply
 public byte[] KeyVerifier;    // Reply
 public byte[] Signature;     // Reply

 public SCTKeyInfo()
 {
 }

 public string ToXmlString()
 {
  string data = null;
  XmlSerializer ser = new XmlSerializer(typeof(SCTKeyInfo));
  using(StringWriter sw = new StringWriter())
  {
   ser.Serialize(sw, this);
   sw.Flush();
   data = sw.ToString();
   return data;
  }
 }

 public static SCTKeyInfo FromXmlString(string xmlString)
 {
  if ( xmlString == null )
   throw new ArgumentNullException("xmlString");

  SCTKeyInfo r = null;
  XmlSerializer ser = new XmlSerializer(typeof(SCTKeyInfo));
  using (StringReader sr = new StringReader(xmlString))
  {
   r = (SCTKeyInfo)ser.Deserialize(sr);
  }
  return r;
 }
}

//
// Client Method
//
public SecurityContextToken GetSCT(string userName, string password)
{
 if ( userName == null || userName.Length == 0 )
  throw new ArgumentNullException("userName");
 if ( password == null || password.Length == 0 )
  throw new ArgumentNullException("password");

 // If we already have a current SCT for this user, return it.
 // "sctList" is just a private static Hashtable.
 SecurityContextToken curSCT = (SecurityContextToken)sctList[userName];
 if ( curSCT != null )
  if ( curSCT.IsExpired )   // Remove expired token; continue.
   sctList.Remove(userName);
  else
   return curSCT;    // Return current SCT.

 // Load server’s RSA.  Could get from Assembly, file, or other.
 System.Security.Cryptography.RSACryptoServiceProvider rsa =
  SnkUtil.GetPublicKeyFromAssembly(Assembly.GetExecutingAssembly());
 
 // Generate new random private RSA PKI for this session.
 System.Security.Cryptography.RSACryptoServiceProvider clientRsa =
  new System.Security.Cryptography.RSACryptoServiceProvider();

 // Create Request.
 SCTKeyInfo ki = new SCTKeyInfo();
 byte[] key1 = Utils.GetRandomBytes(32); // 32 bytes each side.
 string salt = Convert.ToBase64String(Utils.GetRandomBytes(10)).Substring(0, 10);
 string saltun = salt + userName;
 string saltpw = salt + password;
 byte[] unBytes = Encoding.UTF8.GetBytes(saltun);
 byte[] pwBytes = Encoding.UTF8.GetBytes(saltpw);
 ki.Key = rsa.Encrypt(key1, false);
 ki.Username = rsa.Encrypt(unBytes, false);
 ki.Password = rsa.Encrypt(pwBytes, false);
 
 RSAParameters clientParms = clientRsa.ExportParameters(false);
 byte[] mod1 = new byte[64];
 byte[] mod2 = new byte[64];
 Buffer.BlockCopy(clientParms.Modulus, 0, mod1, 0, 64);
 Buffer.BlockCopy(clientParms.Modulus, 64, mod2, 0, 64);
 ki.Mod1 = rsa.Encrypt(mod1, false);
 ki.Mod2 = rsa.Encrypt(mod2, false);
 ki.Exponent = clientParms.Exponent;

 // Sign Request.
 string sigData =
  Convert.ToBase64String(ki.Key) +
  Convert.ToBase64String(ki.Username) +
  Convert.ToBase64String(ki.Password) +
  Convert.ToBase64String(ki.Mod1) +
  Convert.ToBase64String(ki.Mod2) +
  Convert.ToBase64String(ki.Exponent);
 byte[] sigBytes = Encoding.UTF8.GetBytes(sigData);
 ki.Signature = clientRsa.SignData(sigBytes, new SHA1CryptoServiceProvider());

 // Send request.
 SoapEnvelope se = new SoapEnvelope();
 se.SetBodyObject(ki);
 SCTKeyInfo rki = (SCTKeyInfo)base.SendRequestResponse("GetSCT", se).GetBodyObject(typeof(SCTKeyInfo));
 
 if ( rki == null ||
  rki.Key == null || rki.Key.Length == 0 ||
  rki.KeyVerifier == null || rki.KeyVerifier.Length == 0 ||
  rki.SCTExpires == null || rki.SCTExpires.Length == 0 ||
  rki.SCTIdentifier == null || rki.SCTIdentifier.Length == 0 ||
  rki.UTID == null || rki.UTID.Length == 0 )
  throw new Exception("Reply Format Error.");

 // Verify Signature.
 string data =
  Convert.ToBase64String(rki.Key) +
  rki.UTID +
  rki.SCTIdentifier +
  rki.SCTExpires +
  Convert.ToBase64String(rki.KeyVerifier);
 byte[] dataBytes = Encoding.UTF8.GetBytes(data);
 if ( ! rsa.VerifyData(dataBytes, new SHA1CryptoServiceProvider(), rki.Signature) )
  throw new Exception("Could not verify hash.");
 
 // Decrypt server’s key2.
 byte[] key2 = clientRsa.Decrypt(rki.Key, false);
 if ( key2.Length != 32 )
  throw new Exception("Invalid key size in reply.");
 // Create shared key.  Both sides use 16 byte keys.
 // Interleave them to get a 32 byte key, then get first 16 bytes for sKey.
 // We could use the full 32 byte key if SCT allowed 32 bytes in future.
 byte[] tmpKey = Utils.InterleaveArrays(key1, key2);
 byte[] sKey = new byte[16];
 Buffer.BlockCopy(tmpKey, 0, sKey, 0, sKey.Length);
 
 // Verify Server’s KeyVerifier.  This verifies the server calculated
 // the same key we generated.  It also verifies the same username and
 // password was received by server and not modified in-the-middle.
 // If this passes, we know the server has the same key we have.  Note
 // at no time is any part of the sKey exposed.  Only a HMACSHA keyed hash,
 // which is also sent encrypted.
 SHA1 sha = SHA1.Create();
 byte[] skv = clientRsa.Decrypt(rki.KeyVerifier, false);
 string vData = userName + saltpw + Convert.ToBase64String(tmpKey);
 byte[] v = Encoding.UTF8.GetBytes(vData);
 byte[] ckv = sha.ComputeHash(v);
 if ( ! Utils.ArraysEqual(skv, ckv) )
  throw new Exception("Server key does not match calculated key.");

 // Create new UT and SCT.  The SCT is the base token for the UT.
 // Neither the UT or SCT is cached at client side.  Client should
 // hold onto the SCT ref until session is complete.
 UsernameToken unt = new UsernameToken(userName, Convert.ToBase64String(ki.Password), PasswordOption.SendNone);
 unt.Id = rki.UTID;
 SecurityContextToken sct = new SecurityContextToken(unt, rki.SCTIdentifier);
 sct.KeyBytes = sKey; // SCTs require 16 byte Keys.
 DateTime expires = Utils.ReadDateTimeUtc(rki.SCTExpires);
 expires = expires.ToLocalTime();
 sct.LifeTime = new LifeTime(expires);
 Debug.WriteLine("Expires:"+expires.ToString());
 // Add SCT to static Hashtable for this username.
 sctList[userName] = sct;
 return sct;
}

//
// Server Method
//
[SoapMethod("GetSCT")]
public SCTKeyInfo GetSCT(SCTKeyInfo ki)
{
 if ( ki == null )
  throw new ArgumentNullException("ki");
 if ( ki.Key == null || ki.Key.Length == 0 ||
  ki.Username == null || ki.Username.Length == 0 ||
  ki.Password == null || ki.Password.Length == 0 ||
  ki.Mod1 == null || ki.Mod1.Length == 0 ||
  ki.Mod2 == null || ki.Mod2.Length == 0 ||
  ki.Signature == null || ki.Signature.Length == 0 ||
  ki.Exponent == null || ki.Exponent.Length == 0 )
  throw new Exception("Format Error");

 // Load RSA private key from secure location.  This would
 // be done once is a static field, but shown here inside the method.
 string privSnk = @"v:\wsesimpletcpdll\wsesimpletcpdll.snk";
 System.Security.Cryptography.RSACryptoServiceProvider rsa =
  SnkUtil.GetRSAFromSnkFile(privSnk);

 // Get client’s public key from msg.
 System.Security.Cryptography.RSACryptoServiceProvider clientRsa =
  new RSACryptoServiceProvider();
 RSAParameters clientParms = new RSAParameters();
 byte[] mod1 = rsa.Decrypt(ki.Mod1, false);
 byte[] mod2 = rsa.Decrypt(ki.Mod2, false);
 if ( mod1.Length != 64 || mod2.Length != 64 )
  throw new Exception("Invalid format.");
 byte[] modulus = new byte[128];
 Buffer.BlockCopy(mod1, 0, modulus, 0, 64);
 Buffer.BlockCopy(mod2, 0, modulus, 64, 64);
 clientParms.Modulus = modulus;
 clientParms.Exponent = ki.Exponent;
 clientRsa.ImportParameters(clientParms);

 // Verify request msg signature.
 string sigData =
  Convert.ToBase64String(ki.Key) +
  Convert.ToBase64String(ki.Username) +
  Convert.ToBase64String(ki.Password) +
  Convert.ToBase64String(ki.Mod1) +
  Convert.ToBase64String(ki.Mod2) +
  Convert.ToBase64String(ki.Exponent);
 byte[] sigBytes = Encoding.UTF8.GetBytes(sigData);
 if ( ! clientRsa.VerifyData(sigBytes,new SHA1CryptoServiceProvider(), ki.Signature) )
  throw new Exception("Invalid signature.");

 // Generate shared key.  32 bytes each side for a 64 byte total.
 // We only take first 16 bytes of result as max allowed by SCT.
 byte[] key2 = Utils.GetRandomBytes(32);
 byte[] key1 = rsa.Decrypt(ki.Key, false);
 if ( key1.Length != 32 )
  throw new Exception("Invalid request.");
 byte[] tmpKey = Utils.InterleaveArrays(key1, key2);
 byte[] sKey = new byte[16];
 Buffer.BlockCopy(tmpKey, 0, sKey, 0, sKey.Length);

 string saltun = Encoding.UTF8.GetString(rsa.Decrypt(ki.Username, false));
 if ( saltun.Length <= 10 )
  throw new Exception("Invalid username or password size.");
 string saltpw = Encoding.UTF8.GetString(rsa.Decrypt(ki.Password, false));
 if ( saltpw.Length <= 10 )
  throw new Exception("Invalid username or password size.");
 string userName = saltun.Remove(0, 10);
 string pw = saltpw.Remove(0, 10);

 // Authenticate Windows User. Don’t cache the UT.
 WindowsPrincipal wp;
 bool allowed = WinLogon.TryLogonAs(null, userName, pw, LogonType.Network, out wp);
 if ( ! allowed )
  throw new Exception("Invalid username or password.");

 // Logon good.  Create server side SecurityContextToken.
 // Note: We still don’t store plain text pw in UT so it does not
 // "float" around in memory.  The encrypted version is stored.
 byte[] encPW = rsa.Encrypt(Encoding.UTF8.GetBytes(saltpw), false);
 UsernameToken ut = new UsernameToken(userName, Convert.ToBase64String(encPW));
 ut.Principal = wp; // Can now ref windows user groups from UT.
 
 SecurityContextToken sct = new SecurityContextToken(ut);
 DateTime expires = DateTime.Now.AddMinutes(DefaultExpireMins);
 DateTime utcExpires = expires.ToUniversalTime();
 sct.LifeTime = new LifeTime(expires);
 sct.KeyBytes = sKey; // 16 byte key for SCT.
 Debug.WriteLine("s key:"+Convert.ToBase64String(sct.KeyBytes));
 Debug.WriteLine("SCT Expires:"+sct.LifeTime.Expires.ToString());

 // Create reply.
 SCTKeyInfo rki = new SCTKeyInfo();
 rki.Key = clientRsa.Encrypt(key2, false);
 rki.UTID = ut.Id;
 rki.SCTIdentifier = sct.Identifier;
 rki.SCTExpires = Utils.StoreDateTimeUtc(utcExpires);
 
 // Create KeyVerifier and encrypt with client’s public key.
 // The encryption part is probably not nessasary, but does add security
 // as it prevents Dictionary attacks trying to guess the inputs to the hash.
 SHA1 sha = SHA1.Create();
 string vData = userName + saltpw + Convert.ToBase64String(tmpKey);
 byte[] v = Encoding.UTF8.GetBytes(vData);
 rki.KeyVerifier = clientRsa.Encrypt(sha.ComputeHash(v), false);

 // Sign the reply.
 string dataString =
  Convert.ToBase64String(rki.Key) +
  rki.UTID +
  rki.SCTIdentifier +
  rki.SCTExpires +
  Convert.ToBase64String(rki.KeyVerifier);
 byte[] dataBytes = Encoding.UTF8.GetBytes(dataString);
 rki.Signature = rsa.SignData(dataBytes, new SHA1CryptoServiceProvider());
 
 SecurityContextTokenManager.Cache(sct);
 return rki;
}

//
// Utils Helpers
//
public class Utils
{
  private Utils() { }

public static byte[] InterleaveArrays(byte[] ba1, byte[] ba2)
{
 if ( ba1 == null  )
  throw new ArgumentNullException("ba1");
 if ( ba2 == null )
  throw new ArgumentNullException("ba2");
 if ( ba1.Length != ba2.Length )
  throw new ArgumentException("ba1 length must equal ba2 length.");
 if ( (ba1.Length % 2) > 0 )
  throw new ArgumentException("arrays must be an even length.");

 byte[] key = new byte[ba1.Length * 2];
 int step = 0;
 for(int i=0; i < ba1.Length; i++)
 {
  key[step] = ba1[i];
  key[step+1] = ba2[i];
  step+=2;
 }
 return key;
}

public static byte[] GetRandomBytes(int len)
{
 if ( len < 1 )
  throw new ArgumentOutOfRangeException("len must be greater then >= 1.");

 byte[] random = new byte[len];
 RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
 rng.GetBytes(random); // The array is now filled with cryptographically strong random bytes.
 return random;
}

/// <summary>
/// Returns string formatted in Zulu (UTC) time.  value must be UTC DateTime.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string StoreDateTimeUtc(DateTime value)
{
 // Date expected to be UTC date already.
 // e.g 2003-10-26T14:33:41.1234567Z
 return value.ToString("yyyy-MM-ddTHH:mm:ssZ",
  CultureInfo.InvariantCulture);
}

/// <summary>
/// Parses the UTC formatted string, returning DateTime in UTC.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static DateTime ReadDateTimeUtc(string value)
{
 return DateTime.Parse(value, CultureInfo.InvariantCulture,
  DateTimeStyles.AdjustToUniversal);
}
} // End class.


William

This entry was posted in WSE. Bookmark the permalink.

4 Responses to Get SecurityContextToken C# Code

  1. Unknown says:

    http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery http://www.adapterlist.com/asus/w1000g.htm asus w1000g battery

  2. Unknown says:

    http://www.batterylaptoppower.com/gateway/squ-414.htm gateway squ-414 battery http://www.batterylaptoppower.com/gateway/solo-1400.htm gateway solo 1400 battery http://www.batterylaptoppower.com/gateway/solo-1450.htm gateway solo 1450 battery http://www.batterylaptoppower.com/gateway/bat0016.htm gateway bat0016 battery http://www.batterylaptoppower.com/gateway/m1200.htm gateway m1200 battery http://www.batterylaptoppower.com/gateway/m1300.htm gateway m1300 battery http://www.batterylaptoppower.com/gateway/m500.htm gateway m500 battery http://www.batterylaptoppower.com/gateway/m505.htm gateway m505 battery http://www.batterylaptoppower.com/gateway/btp-68b3.htm gateway btp-68b3 battery http://www.batterylaptoppower.com/gateway/btp-51b3.htm gateway btp-51b3 battery http://www.batterylaptoppower.com/hp/hstnn-db11.htm hp hstnn-db11 battery http://www.batterylaptoppower.com/hp/nc8230.htm hp nc8230 battery http://www.batterylaptoppower.com/hp/nc8200.htm hp nc8200 battery http://www.batterylaptoppower.com/hp/nw8200.htm hp nw8200 battery http://www.batterylaptoppower.com/hp/nx8200.htm hp nx8200 battery http://www.batterylaptoppower.com/hp/nc8430.htm hp nc8430 battery http://www.batterylaptoppower.com/hp/pb992a.htm hp pb992a battery http://www.batterylaptoppower.com/hp/nx7000.htm hp nx7000 battery http://www.batterylaptoppower.com/hp/presario-x1000.htm hp presario x1000 battery http://www.batterylaptoppower.com/hp/presario-x1100.htm hp presario x1100 battery http://www.batterylaptoppower.com/hp/presario-x1200.htm hp presario x1200 battery http://www.batterylaptoppower.com/hp/presario-x1300.htm hp presario x1300 battery http://www.batterylaptoppower.com/hp/presario-x1400.htm hp presario x1400 battery http://www.batterylaptoppower.com/hp/zt3000.htm hp zt3000 battery http://www.batterylaptoppower.com/hp/zt3100.htm hp zt3100 battery http://www.batterylaptoppower.com/hp/zt3200.htm hp zt3200 battery http://www.batterylaptoppower.com/hp/zt3300.htm hp zt3300 battery http://www.batterylaptoppower.com/hp/zt3400.htm hp zt3400 battery http://www.batterylaptoppower.com/hp/nx6120.htm hp nx6120 battery http://www.batterylaptoppower.com/hp/pb994a.htm hp pb994a battery http://www.batterylaptoppower.com/hp/nc6100.htm hp nc6100 battery http://www.batterylaptoppower.com/hp/nc6120.htm hp nc6120 battery http://www.batterylaptoppower.com/hp/nx6100.htm hp nx6100 battery http://www.batterylaptoppower.com/hp/nc6400.htm hp nc6400 battery http://www.batterylaptoppower.com/hp/nc6230.htm hp nc6230 battery http://www.batterylaptoppower.com/hp/nc6110.htm hp nc6110 battery http://www.batterylaptoppower.com/hp/dv2000.htm hp dv2000 battery http://www.batterylaptoppower.com/hp/dv2100.htm hp dv2100 battery http://www.batterylaptoppower.com/hp/dv2200.htm hp dv2200 battery http://www.batterylaptoppower.com/hp/dv6000.htm hp dv6000 battery http://www.batterylaptoppower.com/hp/dv9000.htm hp dv9000 battery http://www.batterylaptoppower.com/hp/dv9200.htm hp dv9200 battery http://www.batterylaptoppower.com/hp/dv9100.htm hp dv9100 battery http://www.batterylaptoppower.com/hp/dv9500.htm hp dv9500 battery http://www.batterylaptoppower.com/hp/dv9600.htm hp dv9600 battery

  3. Unknown says:

    http://www.akkuliste.com/asus/m67.htm asus m67 akku http://www.akkuliste.com/asus/m67n.htm asus m67n akku http://www.akkuliste.com/asus/m68.htm asus m68 akku http://www.akkuliste.com/asus/m68n.htm asus m68n akku http://www.akkuliste.com/asus/m6000.htm asus m6000 akku http://www.akkuliste.com/asus/a42-m6-silver.htm asus a42-m6 silver akku http://www.akkuliste.com/asus/m6000-silver.htm asus m6000 silver akku http://www.akkuliste.com/asus/m6-silver.htm asus m6 silver akku http://www.akkuliste.com/clevo/m540.htm clevo m540 akku http://www.akkuliste.com/clevo/mobinote-m-54g.htm clevo mobinote m 54g akku http://www.akkuliste.com/clevo/mobinote-m54v.htm clevo mobinote m54v akku http://www.akkuliste.com/clevo/mobinote-m-55g.htm clevo mobinote m 55g akku http://www.akkuliste.com/clevo/mobinote-m55v.htm clevo mobinote m55v akku http://www.akkuliste.com/clevo/mobinote-m-540g.htm clevo mobinote m 540g akku http://www.akkuliste.com/clevo/mobinote-m540v.htm clevo mobinote m540v akku http://www.akkuliste.com/clevo/mobinote-m-541g.htm clevo mobinote m 541g akku http://www.akkuliste.com/clevo/mobinote-m541v.htm clevo mobinote m541v akku http://www.akkuliste.com/clevo/mobinote-m-545g.htm clevo mobinote m 545g akku http://www.akkuliste.com/clevo/mobinote-m545v.htm clevo mobinote m545v akku http://www.akkuliste.com/clevo/mobinote-m-550g.htm clevo mobinote m 550g akku http://www.akkuliste.com/clevo/mobinote-m550v.htm clevo mobinote m550v akku http://www.akkuliste.com/clevo/mobinote-m-551g.htm clevo mobinote m 551g akku http://www.akkuliste.com/clevo/mobinote-m551v.htm clevo mobinote m551v akku http://www.akkuliste.com/clevo/mobinote-m-555g.htm clevo mobinote m 555g akku http://www.akkuliste.com/clevo/mobinote-m555v-serie.htm clevo mobinote m555v serie akku http://www.akkuliste.com/compaq/presario-1200.htm compaq presario 1200 akku http://www.akkuliste.com/compaq/presario-1600.htm compaq presario 1600 akku http://www.akkuliste.com/compaq/presario-1800.htm compaq presario 1800 akku http://www.akkuliste.com/compaq/nw8000.htm compaq nw8000 akku http://www.akkuliste.com/compaq/nc8000.htm compaq nc8000 akku http://www.akkuliste.com/compaq/v1000.htm compaq v1000 akku http://www.akkuliste.com/compaq/nc6000.htm compaq nc6000 akku http://www.akkuliste.com/compaq/nx5000.htm compaq nx5000 akku http://www.akkuliste.com/compaq/n600.htm compaq n600 akku http://www.akkuliste.com/compaq/n600c.htm compaq n600c akku http://www.akkuliste.com/compaq/n610c.htm compaq n610c akku http://www.akkuliste.com/compaq/n610v.htm compaq n610v akku http://www.akkuliste.com/compaq/n620c.htm compaq n620c akku http://www.akkuliste.com/compaq/nx9000.htm compaq nx9000 akku http://www.akkuliste.com/compaq/nx9005.htm compaq nx9005 akku http://www.akkuliste.com/compaq/nx9010.htm compaq nx9010 akku http://www.akkuliste.com/compaq/nx9020.htm compaq nx9020 akku http://www.akkuliste.com/compaq/hstnnib12.htm compaq hstnnib12 akku http://www.akkuliste.com/asus/m67.htm asus m68 akku

  4. Sven says:

    William –Thanks for the guidance.I wonder why you are creating custom methods to serialize and deserialize your SCTKeyInfo objects? They don\’t seem to be used anywhere else in the code?

Comments are closed.