NullReferenceException on Encrypt Method

Nov 22, 2011 at 11:07 AM
Edited Nov 22, 2011 at 11:09 AM

I was just trying your lib and followed all steps, but i receive a NullReferenceException when executing this method.

(SecurEntityLib.SecurEntity)entry.Entity).Encrypt();

Please provide detail messages to help us understand what's the issue!

Another thing:
You have mentioned nothing about abstract method (GetPrimaryKeyFieldName).
Should i just return string with attribute name that has the [Key] attribute?
What if i have multiple column that make my primary key?

Coordinator
Nov 23, 2011 at 12:08 AM

Can you please confirm the configuration of your SecurEntity encryption certificate? You can do that by running both of the following commands from a cmd.exe window and then searching for the "SecurEntity" friendly name string. Please reply with the dump that contains that SecurEntity certificate.

certutil -store -user -v MY 



certutil -store -user -v MY 



certutil -store -v MY 


Nov 23, 2011 at 1:09 PM

Here is data you asked.

 

X509 Certificate:
Version: 3
Serial Number: 49b144ba6c3e358a48996dcc74cedb1d
Signature Algorithm:
    Algorithm ObjectId: 1.2.840.113549.1.1.5 sha1RSA
    Algorithm Parameters:
    05 00
Issuer:
    CN=Vincenzo-PC\Vincenzo

 NotBefore: 12/07/2011 10:10
 NotAfter: 11/07/2012 16:10

Subject:
    CN=Vincenzo-PC\Vincenzo

Public Key Algorithm:
    Algorithm ObjectId: 1.2.840.113549.1.1.1 RSA (RSA_SIGN)
    Algorithm Parameters:
    05 00
Public Key Length: 1024 bits
Public Key: UnusedBits = 0
    0000  30 81 89 02 81 81 00 c8  04 ee 48 66 d8 e7 68 2f
    0010  75 b9 97 25 5e 09 26 44  d7 0e 86 58 15 ec 99 ad
    0020  f1 e5 1e 3f 82 ca 27 47  c7 0e 96 b2 bd 97 c2 9e
    0030  cf 14 40 c4 cc db 18 28  de 05 7e 65 0f 99 5e 46
    0040  8e 42 8d 97 79 00 2a 69  3b d5 5a 50 fa 1b e0 82
    0050  9f 88 88 ae 0c b6 05 75  d8 34 23 cb 69 ac a2 c9
    0060  93 9d 49 f3 46 32 01 4b  a9 aa c3 2c c8 86 d7 fb
    0070  4d fe 56 9a 24 6b fc 6c  45 22 12 cd 53 e4 6f ce
    0080  f5 d7 2e c7 3d 2f 55 02  03 01 00 01
Certificate Extensions: 0
Signature Algorithm:
    Algorithm ObjectId: 1.2.840.113549.1.1.5 sha1RSA
    Algorithm Parameters:
    05 00
Signature: UnusedBits=0
    0000  30 68 8d 9e 9c 8d 0d 17  28 df f6 f1 98 c7 37 2c
    0010  77 7c 88 3c 8a 1c 0d f9  04 bf 3d e9 2a 96 18 59
    0020  5a f6 e1 ec e0 48 9b d7  01 49 30 a7 49 aa 0b 5c
    0030  13 91 24 d7 50 7f 11 8f  48 4d 0d 20 5c 5d cc 0a
    0040  f7 db 5f b7 db 7e e2 db  9a d2 72 74 70 0e 4e c3
    0050  bc 81 a1 ff c5 0c 81 6a  93 d9 3b b9 e1 73 b5 6e
    0060  57 c6 33 5e db 88 de 80  81 01 ed 5e 2f d1 14 02
    0070  8d 16 ed 37 7c 5a f6 44  78 f2 1d d4 f9 54 7a 7d
Signature matches Public Key
Root Certificate: Subject matches Issuer
Key Id Hash(rfc-sha1): 3d 35 f9 35 1c 23 3f a2 1d 53 ca 41 4d 89 54 4e 24 ad 68 cc
Key Id Hash(sha1): 78 2b d5 2e 26 aa df f4 51 7f b2 e2 d7 4a 20 28 ec 91 cb 0d
Cert Hash(md5): 9c 70 e0 f5 f3 8d 7e 6f 0d 92 17 59 eb fc 6c 0b
Cert Hash(sha1): 74 c1 2d 7f 01 fd e8 51 57 ef d9 ba 6c b9 8d ac 7e 66 f4 a1

  CERT_FRIENDLY_NAME_PROP_ID(11):
    SecurEntity

  CERT_MD5_HASH_PROP_ID(4):
    9c 70 e0 f5 f3 8d 7e 6f 0d 92 17 59 eb fc 6c 0b

  CERT_KEY_IDENTIFIER_PROP_ID(20):
    78 2b d5 2e 26 aa df f4 51 7f b2 e2 d7 4a 20 28 ec 91 cb 0d

  CERT_KEY_PROV_INFO_PROP_ID(2):
    Key Container = {6FD98C4B-78CC-4ECD-8138-CC618AA18241}
  Unique container name: 41f8e2932c1f449cf364f6b63798d32f_68e5c5d6-a10a-410f-a6be-85408b75a408
    Provider = Microsoft Strong Cryptographic Provider
    ProviderType = 1
    Flags = 0
    KeySpec = 2 -- AT_SIGNATURE

  CERT_SHA1_HASH_PROP_ID(3):
    74 c1 2d 7f 01 fd e8 51 57 ef d9 ba 6c b9 8d ac 7e 66 f4 a1

  CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID(25):
    c1 ae d2 53 f3 27 8c ef 5e 03 db 7e 2a a6 1b b5

  CERT_SIGNATURE_HASH_PROP_ID(15):
    56 82 0e 33 fe bd 93 f9 73 2f 09 24 55 7d 23 53 3a 12 c2 0e
  Unique container name: 41f8e2932c1f449cf364f6b63798d32f_68e5c5d6-a10a-410f-a6be-85408b75a408
  PP_KEYSTORAGE = 1
    CRYPT_SEC_DESCR -- 1
  KP_PERMISSIONS = 3f (63)
    CRYPT_ENCRYPT -- 1
    CRYPT_DECRYPT -- 2
    CRYPT_EXPORT -- 4
    CRYPT_READ -- 8
    CRYPT_WRITE -- 10 (16)
    CRYPT_MAC -- 20 (32)

  D:(A;ID;GAGR;;;SY)(A;ID;GAGR;;;BA)(A;ID;GAGR;;;S-1-5-21-3871202306-2175730410-1011070285-1000)

    Allow Full Control  NT AUTHORITY\SYSTEM
    Allow Full Control  BUILTIN\Administrators
    Allow Full Control  Vincenzo-PC\Vincenzo


Private Key:
  PRIVATEKEYBLOB
  Version: 2
  aiKeyAlg: 0x2400
    CALG_RSA_SIGN
    Algorithm Class: 0x2000(1) ALG_CLASS_SIGNATURE
    Algorithm Type: 0x400(2) ALG_TYPE_RSA
    Algorithm Sub-id: 0x0(0) ALG_SID_RSA_ANY
  0000  52 53 41 32                                        RSA2
  0000  ...
  024c
Signature test passed

Coordinator
Nov 23, 2011 at 3:36 PM

Ah - that's a signature-only certificate. You need one which supports encryption.

Actually, technically, the code doesn't check the capabilities of the certificate itself. It's just that the certificate private key must support encryption. The problem is that, when you have a certificate that's signature-only, that almost always means that the underlying key is signature-only as well.

Nov 23, 2011 at 3:56 PM
Edited Nov 23, 2011 at 3:56 PM

Hello and thank you for your prompt reply.
I agree with you, certificate is surely wrong, i'm going to fix that.
I think would be better a Exception message explaining that something is going wrong with certificate! (example: missing friendlyname, or signature only certificate).
I was going crazy checking my classes and code before understand was something due to certificate.

Another thing:
You have mentioned nothing about abstract method (GetPrimaryKeyFieldName).
Should i just return string with attribute name that has the [Key] attribute?
What if i have multiple column that make my primary key?

Coordinator
Nov 28, 2011 at 3:04 AM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Coordinator
Nov 28, 2011 at 3:12 AM

Yes, regarding GetPrimaryKeyFieldName, that's correct. Here's a comment from _CheckSecurEntityID. The purpose of the abstract method is so we know programmatically which property is the PK, and hence which property to omit from the hash.

                    //
                    // N.B. - this library assumes that the Primary Key of any
                    // SecurEntity is of type int. However, since that value
                    // is generated automatically by SQL the first time the
                    // object/row is written, it can't be used in the hash
                    // computation.
                    //
                    // Instead, this GUID property is used in order to support
                    // the cryptographic binding of relationships between
                    // SecurEntity objects.
                    //

 

Dec 13, 2011 at 10:14 AM

What if i have multiple key fields?

Coordinator
Dec 17, 2011 at 12:12 AM

The current code assumes that the primary key is dynamically assigned by SQL when a new row is committed. For that reason, the primary key field can't be included in the hash of that row, since as soon as the row is written for the first time, that hash would be wrong.

(Note that, regarding the security of that approach, the mitigation is that our POCO objects do include the primary key field of child objects in their hash computation. So an attacker can't modify those relationships without being caught. As long is the primary key field is only used for that purpose, we're okay.)

To your point, the question is whether your additional PK field(s) exhibit the behavior above. If they're also auto-generated by SQL, then the library would need to be extended to handle this. But that seems unlikely, given a typical schema. If you want to give some specifics, we could work through it.