Retired Microsoft Blog disclaimer

This directory is a mirror of retired "Decrypt My World" MSDN blog and is provided as is. All posting authorship and copyrights belong to respective authors.

Posts on this page:

Original URL: https://blogs.msdn.microsoft.com/alejacma/2008/10/30/how-to-clean-up-expired-certs-on-your-smart-card/
Post name: How to clean up expired certs on your smart card
Original author: Alejandro Campos Magencio
Posting date: 2008-10-30T06:37:00+00:00


Hi all,

The other day a colleague of mine was trying to renew his smart card certificate, but he got an error telling him that there was not enough space in the card to store the new cert. Sohe asked me: Alex, how can I delete a certificate from my smart card so there is room for a new one?

Well, admins generally have special tools for this task, but sometimes it may be necessary for an end/admin user to manually free up space on an smart card in order to enroll or renew certs. If you are in this situation, you may follow these steps:

1) Run the following command to get a list of certificates stored in the smart card:

certutil -scinfo > output.txt

Note: Certutil tool should be included on Windows Vista/Server 2008 by default. You may also get it from Windows Server 2003 Admin Pack, for instance.

Cerutil may request the smart card PIN several times. You can safely ignore these requests by pressing Esc every time. You will finally get a dialog with a list of certificates in the card (in my particular case I got 3 certs, and one of them had already expired). Now close that dialog and wait until certutil finishes running.

2)Take a look to output.txt.For example,in my case the first cert (“Certificate 0”) was the expired one (I could see strings like “Chain on smart card is invalid”, “CERT_TRUST_IS_NOT_TIME_VALID”and “Expired certificate”). Copy its related “Key Container” value (“f6138188-3725-4c2b-8cf6-9c421d8bee69” in my case).

3)Run the following command to remove the certificate associated to the key container you copied before:

certutil -delkey -csp "Microsoft Base Smart Card Crypto Provider" "f6138188-3725-4c2b-8cf6-9c421d8bee69"

Note: your smart card CSP may be different. Use yours.

Now you should be able to store a new cert in the card.

I hope this helps.

Kind regards,

Alex (Alejandro Campos Magencio)

Original URL: https://blogs.msdn.microsoft.com/alejacma/2008/10/23/rsacryptoserviceprovider-encrypt-returns-key-not-valid-for-use-in-specified-state-error/
Post name: RSACryptoServiceProvider.Encrypt returns "Key not valid for use in specified state" error
Original author: Alejandro Campos Magencio
Posting date: 2008-10-23T05:19:00+00:00


Hi all,

When executing RSACryptoServiceProvider.Encrypt method (see How to generate key pairs, encrypt and decrypt data with .NET (C#) for an example), you may get a System.Security.Cryptography.CryptographicException. According to MSDN, this is to be expected in several circumstances:

The cryptographic service provider (CSP) cannot be acquired. -or-

The length of the rgb parameter is greater than the maximum allowed length. -or-

The fOAEP parameter is true and OAEP padding is not supported.

 

In my case the error message of the exception was "Key not valid for use in specified state". Weird... Well, it took me a while to realize that this error message was certainly misleading! The key was just fine, the issue was that I was passing too many bytes to the Encrypt method! Check in MSDN the maximum length allowed by the different combinations of operating systems and padding.

I hope this helps.

Kind regards,

 

Alex (Alejandro Campos Magencio)

Original URL: https://blogs.msdn.microsoft.com/alejacma/2008/10/23/how-to-generate-key-pairs-encrypt-and-decrypt-data-with-net-c/
Post name: How to generate key pairs, encrypt and decrypt data with .NET (C#)
Original author: Alejandro Campos Magencio
Posting date: 2008-10-23T05:03:00+00:00


Hi all,


The other day a colleague of mine asked me if I hada .NET version of the C++ sample inHow to generate key pairs, encrypt and decrypt data with CryptoAPIpost. C++ sample calls CryptoAPI directly (and you know we can do the same thing in .NET through P/Invoke), but the idea was to use System.Security classes in order to get a pure .NET solution. The answer is yes, I have such sample, and here it is:

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace EncryptDecrypt
{
class Program
{
// Main
static void Main(string[] args)
{
if ((args.Length == 3) && (args[0].Equals("k")))
{
// Generate a new key pair
Keys(args[1], args[2]);

}
else if ((args.Length == 4) && (args[0].Equals("e")))
{
// Encrypt a file
Encrypt(args[1], args[2], args[3]);

}
else if ((args.Length == 4) && (args[0].Equals("d")))
{
// Decrypt a file
Decrypt(args[1], args[2], args[3]);
}
else {
// Show usage
Console.WriteLine("Usage:");
Console.WriteLine(" - New key pair: EncryptDecrypt k public_key_file private_key_file");
Console.WriteLine(" - Encrypt: EncryptDecrypt e public_key_file plain_file encrypted_file");
Console.WriteLine(" - Decrypt: EncryptDecrypt d private_key_file encrypted_file plain_file");
}

// Exit
Console.WriteLine("\n<< Press any key to continue >>");
Console.ReadKey();
return;

} // Main

// Generate a new key pair
static void Keys(string publicKeyFileName, string privateKeyFileName)
{
// Variables
CspParameters cspParams = null;
RSACryptoServiceProvider rsaProvider = null;
StreamWriter publicKeyFile = null;
StreamWriter privateKeyFile = null;
string publicKey = "";
string privateKey = "";

try
{
// Create a new key pair on target CSP
cspParams = new CspParameters();
cspParams.ProviderType = 1; // PROV_RSA_FULL
//cspParams.ProviderName; // CSP name
cspParams.Flags = CspProviderFlags.UseArchivableKey;
cspParams.KeyNumber = (int)KeyNumber.Exchange;
rsaProvider = new RSACryptoServiceProvider(cspParams);

// Export public key
publicKey = rsaProvider.ToXmlString(false);

// Write public key to file
publicKeyFile = File.CreateText(publicKeyFileName);
publicKeyFile.Write(publicKey);

// Export private/public key pair
privateKey = rsaProvider.ToXmlString(true);

// Write private/public key pair to file
privateKeyFile = File.CreateText(privateKeyFileName);
privateKeyFile.Write(privateKey);
}
catch (Exception ex)
{
// Any errors? Show them
Console.WriteLine("Exception generating a new key pair! More info:");
Console.WriteLine(ex.Message);
}
finally
{
// Do some clean up if needed
if (publicKeyFile != null)
{
publicKeyFile.Close();
}
if (privateKeyFile != null)
{
privateKeyFile.Close();
}
}

} // Keys

// Encrypt a file
static void Encrypt(string publicKeyFileName, string plainFileName, string encryptedFileName)
{
// Variables
CspParameters cspParams = null;
RSACryptoServiceProvider rsaProvider = null;
StreamReader publicKeyFile = null;
StreamReader plainFile = null;
FileStream encryptedFile = null;
string publicKeyText = "";
string plainText = "";
byte[] plainBytes = null;
byte[] encryptedBytes = null;

try
{
// Select target CSP
cspParams = new CspParameters();
cspParams.ProviderType = 1; // PROV_RSA_FULL
//cspParams.ProviderName; // CSP name
rsaProvider = new RSACryptoServiceProvider(cspParams);

// Read public key from file
publicKeyFile = File.OpenText(publicKeyFileName);
publicKeyText = publicKeyFile.ReadToEnd();

// Import public key
rsaProvider.FromXmlString(publicKeyText);

// Read plain text from file
plainFile = File.OpenText(plainFileName);
plainText = plainFile.ReadToEnd();

// Encrypt plain text
plainBytes = Encoding.Unicode.GetBytes(plainText);
encryptedBytes = rsaProvider.Encrypt(plainBytes, false);

// Write encrypted text to file
encryptedFile = File.Create(encryptedFileName);
encryptedFile.Write(encryptedBytes, 0, encryptedBytes.Length);
}
catch (Exception ex)
{
// Any errors? Show them
Console.WriteLine("Exception encrypting file! More info:");
Console.WriteLine(ex.Message);
}
finally
{
// Do some clean up if needed
if (publicKeyFile != null)
{
publicKeyFile.Close();
}
if (plainFile != null)
{
plainFile.Close();
}
if (encryptedFile != null)
{
encryptedFile.Close();
}
}

} // Encrypt

// Decrypt a file
static void Decrypt(string privateKeyFileName, string encryptedFileName, string plainFileName)
{
// Variables
CspParameters cspParams = null;
RSACryptoServiceProvider rsaProvider = null;
StreamReader privateKeyFile = null;
FileStream encryptedFile = null;
StreamWriter plainFile = null;
string privateKeyText = "";
string plainText = "";
byte[] encryptedBytes = null;
byte[] plainBytes = null;

try
{
// Select target CSP
cspParams = new CspParameters();
cspParams.ProviderType = 1; // PROV_RSA_FULL
//cspParams.ProviderName; // CSP name
rsaProvider = new RSACryptoServiceProvider(cspParams);

// Read private/public key pair from file
privateKeyFile = File.OpenText(privateKeyFileName);
privateKeyText = privateKeyFile.ReadToEnd();

// Import private/public key pair
rsaProvider.FromXmlString(privateKeyText);

// Read encrypted text from file
encryptedFile = File.OpenRead(encryptedFileName);
encryptedBytes = new byte[encryptedFile.Length];
encryptedFile.Read(encryptedBytes, 0, (int)encryptedFile.Length);

// Decrypt text
plainBytes = rsaProvider.Decrypt(encryptedBytes, false);

// Write decrypted text to file
plainFile = File.CreateText(plainFileName);
plainText = Encoding.Unicode.GetString(plainBytes);
plainFile.Write(plainText);
}
catch (Exception ex)
{
// Any errors? Show them
Console.WriteLine("Exception decrypting file! More info:");
Console.WriteLine(ex.Message);
}
finally
{
// Do some clean up if needed
if (privateKeyFile != null)
{
privateKeyFile.Close();
}
if (encryptedFile != null)
{
encryptedFile.Close();
}
if (plainFile != null)
{
plainFile.Close();
}
}

} // Decrypt
}
}


If you compare both samples you will see that .NET simplifies the task a lot. But sometimes we won't be able to do withSystem.Security classes exactly the same we can do with CryptoAPI. So don't forget about the API just yet!


I hope this helps.


Kind regards,



Alex (Alejandro Campos Magencio)

Original URL: https://blogs.msdn.microsoft.com/alejacma/2008/10/23/something-has-changed-in-my-life/
Post name: Something has changed in my life
Original author: Alejandro Campos Magencio
Posting date: 2008-10-23T04:50:00+00:00


Hi all,

Sorry I haven't been able to write anything for a few weeks. I've been on vacation + paternity leave... Paternity leave! Yes, I'm a father now! My son Nicolas was born on Sept 11th, 2008, and he's taken pretty much all my free time since. WELCOME TO OUR WORLD NICOLAS!!! I'll try to help you on decrypting it too my son ??

And now I'm back to the office, and to the blog. I'll begin posting new stuff right away.

Cheers,

Alex (Alejandro Campos Magencio)

Original URL: https://blogs.msdn.microsoft.com/alejacma/2008/09/08/the-use-of-msxml-is-not-supported-in-net-applications/
Post name: The use of MSXML is not supported in .NET applications
Original author: Alejandro Campos Magencio
Posting date: 2008-09-08T07:33:00+00:00


Hi all,


The other day I was working with a customer of mine on a .NET application which was suffering from a memory leak. The weird thing was that the application could run just fine for 10 days in a rowbefore the memory began growing and growing. What was going on? Why was the Garbage Collector suddenly deciding to stop working? Additionally, this issue was happening with both .NET 1.1 and 2.0. Weird.


So we got a dump of a .NET 1.1 version of the application when the issue began. We used Adplus to take a hang dump we could analize (How to use ADPlus to troubleshoot "hangs" and "crashes").


We loaded SOS debugger extension (the one that comes with .NET Framework 1.1):

0:000>.load sos

And we went to check all objects currently on the heap:

0:000> !dumpheap -stat
Loaded Son of Strike data table version 5 from "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\mscorwks.dll"
Loading the heap objects into our cache.
total 1,958,563 objects
Statistics:
MT Count TotalSize Class Name
...

Almost 2 million objects! That is a lot. Are any of them ready for finalization?

0:000> !finalizequeue
Loaded Son of Strike data table version 5 from "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\mscorwks.dll"
SyncBlock to be cleaned up: 6371
----------------------------------
MTA interfaces to be released: 0
Total STA interfaces to be released: 0
----------------------------------
generation 0 has 215 finalizable objects (0x17daef74->0x17daf2d0)
generation 1 has 0 finalizable objects (0x17daef74->0x17daef74)
generation 2 has 15,317 finalizable objects (0x17da0020->0x17daef74)
Ready for finalization 0 objects (0x17daf2d0->0x17daf2d0) - Freachable queue
All Finalizable Objects Statistics:
MT Count TotalSize Class Name
...

So apparently there are no objects ready to be finalized, but we have 6371 SyncBlocks ready to be cleaned up. Why? What are those SyncBlocks?

0:000> !finalizequeue -detail
To be cleaned Com Data

0x4edc1b8 ComPlusWrapper
0x4edc590 ComPlusWrapper
...
0x4e227b8 ComPlusWrapper
SyncBlock to be cleaned up: 6371
----------------------------------
MTA interfaces to be released: 0
Total STA interfaces to be released: 0
...

Ok, so those SyncBlocks are related to ComPlusWrappers which need to be cleaned up. It seems the application is referencing some COM objects which are not needed anymore.


And what is the Finalizer thread doing that is not cleaning up those objects? Is it too busy?

0:000> !threads
ThreadCount: 23
UnstartedThread: 0
BackgroundThread: 17
PendingThread: 0
DeadThread: 0
PreEmptive GC Alloc Lock
ID ThreadOBJ State GC Context Domain Count APT Exception
0 0x7a4 0x0013e1b8 0xa020 Enabled 0x00000000:0x00000000 0x00138fa0 0 MTA
2 0x484 0x0014a508 0xb220 Enabled 0x00000000:0x00000000 0x00138fa0 0 MTA (Finalizer)
...
0:000> ~2s
0:002> kL100
ChildEBP RetAddr
02a5f980 77f8822a NTDLL!ZwWaitForSingleObject+0xb
02a5f9f4 77f8819b NTDLL!RtlpWaitForCriticalSection+0x9e
02a5f9fc 72e55ff1 NTDLL!RtlEnterCriticalSection+0x46
02a5fa08 72e56010 msxml3!X_CRITICAL_SECTION::Enter+0xc
02a5fa10 72e5b735 msxml3!CSMutex::Enter+0xd
02a5fa20 72e5b6fd msxml3!RemovePointerFromCache+0x2e
02a5fa2c 72e55cfe msxml3!GCObject::~GCObject+0x15
02a5fa38 72e55c21 msxml3!_array<_reference >::`vector deleting destructor'+0xd
02a5fa44 72e5b5b6 msxml3!Base::weakRelease+0x19
02a5fa54 72e5b565 msxml3!Base::_release+0x95
02a5fa5c 72e5685d msxml3!DefaultWriter::Release+0xd
02a5fa74 72e60805 msxml3!assign+0x26
02a5fa8c 72e5ff5f msxml3!NodeData::setText+0x1e
02a5fa98 72e5b5a5 msxml3!Node::finalize+0x73
02a5faa8 72e60b7d msxml3!Base::_release+0x76
02a5fac0 72e6098b msxml3!Node::setNodeParent+0x7f
02a5fae0 72e5ff9a msxml3!Node::_remove+0x90
02a5faec 72e5b5a5 msxml3!Node::finalize+0x65
02a5fafc 72e60ae4 msxml3!Base::_release+0x76
02a5fb14 72e5c36e msxml3!Node::_release+0x77
02a5fb2c 72e5c1a7 msxml3!Node::_release+0x8d
02a5fb40 72e5b54e msxml3!Node::Release+0x26
02a5fb4c 72e70e12 msxml3!release+0x17
02a5fb58 72e70ddf msxml3!DOMNodeList::~DOMNodeList+0x16
02a5fb64 72e56962 msxml3!DOMNamedNodeMapList::`vector deleting destructor'+0x16
02a5fba4 72e5b8e3 msxml3!__comexport::Release+0x62
02a5fbac 79221be1 msxml3!_dispatchEx::Release+0x10
02a5fbdc 79232e77 mscorwks!SafeRelease+0x56
02a5fbf8 79232ea8 mscorwks!IUnkEntry::Free+0x7c
02a5fc04 79232f86 mscorwks!ComPlusWrapper::ReleaseAllInterfaces+0xa
02a5fe3c 79232e0d mscorwks!ComPlusWrapper::ReleaseAllInterfacesCallBack+0x135
02a5fe48 7923303c mscorwks!ComPlusWrapper::Cleanup+0x16
02a5fe58 79233302 mscorwks!ComPlusContextCleanupGroup::CleanUpWrappers+0x19
02a5fe64 792335bc mscorwks!ComPlusApartmentCleanupGroup::ReleaseCleanupGroup+0xe
02a5fe74 792325bb mscorwks!ComPlusApartmentCleanupGroup::ReleaseCleanupGroupCallback+0x51
02a5fe98 792324dc mscorwks!ComPlusApartmentCleanupGroup::CleanUpWrappers+0xa8
02a5fed0 791fea3d mscorwks!ComPlusWrapperCleanupList::CleanUpWrappers+0x84
02a5fedc 791fe9cd mscorwks!SyncBlockCache::CleanupSyncBlocks+0x85
02a5fee0 791bbd18 mscorwks!Thread::DoExtraWorkForFinalizer+0x23
02a5ff20 791cf03c mscorwks!GCHeap::FinalizerThreadStart+0xbb
02a5ffb4 7c57b3bc mscorwks!Thread::intermediateThreadProc+0x44
02a5ffec 00000000 KERNEL32!BaseThreadStart+0x52

Interesting. The Finalizer thread is trying to free an MSXML3 object, it entered a critical section and it's waiting for it to be released. We took a few more dumps and the Finalizer thread always stayed the same. It didn't move a bit. It's hung in there. So no wonder Garbage Collector can't free memory.


Why is Finalizer thread hung on a critical section when freeing MSXML objects?


Well, check this:


The use of MSXML is not supported in .NET applications


MSXML uses threading models and garbage-collection mechanisms that are not compatible with the .NET Framework.


Summing up, we fail to garbage-collect msxml objectsbecause of these incompatibilities. This issue affects all versions of the Framework and MSXML. The only alternative we have is to use .Net's System.Xml namespace to work with XML as suggested by previous article.


I hope this helps.


Cheers,



Alex (Alejandro Campos Magencio)