source: trunk/PKCS1/Library/BleichenbacherSignature.cs @ 1663

Last change on this file since 1663 was 1663, checked in by schomburg, 12 years ago

fixed Help texts
added GuiLogMessages - not working yet

File size: 10.9 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using Org.BouncyCastle.Math;
6using Cryptool.PluginBase;
7
8
9namespace PKCS1.Library
10{
11    class BleichenbacherSignature : Signature, IGuiLogMsg
12    {
13        public BleichenbacherSignature()
14        {
15            this.registerHandOff();
16        }
17
18        protected int m_dataBlockStartPos = 2072;
19        public int DataBlockStartPos
20        {
21            set
22            {
23                //TODO zulässigen Wertebereich weiter einschraenken?
24                if ((int)value > 0 && (int)value < RSAKeyManager.getInstance().RsaKeySize)
25                {
26                    this.m_dataBlockStartPos = (int)value;
27                }
28                else
29                {
30                    this.m_dataBlockStartPos = 2072;
31                }
32            }
33            get
34            {
35                return this.m_dataBlockStartPos;
36            }
37        }
38
39        public override void GenerateSignature()
40        {
41            this.SendGuiLogMsg("Message Generation started", NotificationLevel.Info);
42
43            this.m_KeyLength = RSAKeyManager.getInstance().RsaKeySize;
44
45            int hashDigestLength = Hashfunction.getDigestSize() * 8; // weil Size in Byte zurückgegeben wird
46            int hashIdentLength = Datablock.getInstance().HashFunctionIdent.DERIdent.Length * 4; // weil ein zeichen im string = 4 bit           
47            int keyLength = this.m_KeyLength;
48            BigInteger derIdent = new BigInteger(Datablock.getInstance().HashFunctionIdent.DERIdent, 16);
49            BigInteger datablockLength = BigInteger.ValueOf(hashDigestLength + hashIdentLength + 8); // Länge Datenblock inkl 0-Byte (=8Bit)
50
51            bool isDivByThree = false;
52            BigInteger N = null;
53            BigInteger datablock = null;
54
55            while (false == isDivByThree)
56            {
57                BigInteger hashDigest = new BigInteger(1, Hashfunction.generateHashDigest(Datablock.getInstance().Message, Datablock.getInstance().HashFunctionIdent));
58                // T*2^160 + H
59                datablock = derIdent.Multiply(BigInteger.Two.Pow(hashDigestLength)).Add(hashDigest); // Datablock erstellen; T=HashFuncIdent; H=HashDigest
60                N = (BigInteger.Two.Pow(datablockLength.IntValue)).Subtract(datablock); // N muss vielfaches von 3 sein
61
62                if (0 == (N.Mod(BigInteger.Three)).IntValue)
63                {
64                    isDivByThree = true;
65                }
66                else
67                {
68                    Datablock.getInstance().Message = Datablock.getInstance().Message + " ";
69                }
70            }
71
72            BigInteger sigLengthWithoutZeros = BigInteger.ValueOf(this.m_KeyLength - 15); // 15 weil die ersten 15 bit 0 sind
73            BigInteger startPos = BigInteger.ValueOf(this.m_dataBlockStartPos);
74            BigInteger endPos = startPos.Add(datablockLength);
75            BigInteger sigLengthDivThree = sigLengthWithoutZeros.Divide(BigInteger.Three); // TODO muss Ganzzahl sein
76           
77            BigInteger testbeta = endPos.Subtract(BigInteger.Two.Multiply(sigLengthDivThree)).Subtract(datablockLength); // sollte 34 seinbei keylength 3072
78
79            //2^3057 - 2^ (2038 + 288 + 34) == 2^3057 - 2^2360
80            BigInteger fakeSig = (BigInteger.Two.Pow(sigLengthWithoutZeros.IntValue)).Subtract( BigInteger.Two.Pow( 2 * sigLengthDivThree.IntValue + datablockLength.IntValue + testbeta.IntValue ));
81
82            // 2^3057 - 2^2360 + 2^2072 * N
83            fakeSig = fakeSig.Add( (BigInteger.Two.Pow( startPos.IntValue )).Multiply(datablock) );
84            fakeSig = fakeSig.Add( BigInteger.Two.Pow(startPos.IntValue-8).Multiply(BigInteger.ValueOf(125)) ); // add garbage
85
86            BigInteger fakeSigResult = MathFunctions.cuberoot2(fakeSig);
87
88            byte[] returnByteArray = new byte[this.m_KeyLength / 8]; // KeyLength is in bit
89            Array.Copy(fakeSigResult.ToByteArray(), 0, returnByteArray, returnByteArray.Length - fakeSigResult.ToByteArray().Length, fakeSigResult.ToByteArray().Length);
90
91            this.m_Signature = returnByteArray;
92            this.m_bSigGenerated = true;
93            this.OnRaiseSigGenEvent(SignatureType.Bleichenbacher);
94        }
95
96        /*
97        public void GenerateSignature2()
98        {
99            // RSA Schlüssellänge setzen für Methode in Oberklasse
100            this.m_KeyLength = RSAKeyManager.getInstance().RsaKeySize;
101
102            // TODO prüfen ob Rsa Schlüssel generiert wurde
103            // TODO User mitteilen dass evtl Leerzeichen an message angehangen wurden und in HwControl Digest korrigieren
104            BigInteger T = new BigInteger(Datablock.getInstance().HashFunctionIdent.DERIdent, 16);
105            string test1 = T.ToString(16);
106            BigInteger a = null;
107            bool isDivByThree = false;
108
109            int hashDigestLength = Hashfunction.getDigestSize() * 8; // weil Size in Byte zurückgegeben wird
110            int hashIdentLength = Datablock.getInstance().HashFunctionIdent.DERIdent.Length * 4; // weil ein zeichen im string = 4 bit
111            int datablocklength = hashDigestLength + hashIdentLength + 8; // Länge Datenblock inkl 0-Byte (=8Bit)
112
113            while (false == isDivByThree)
114            {
115                //byte[] hashDigest = Hashfunction.generateHashDigest(Datablock.getInstance().Message, Datablock.getInstance().HashFunctionIdent);
116                //BigInteger testBigInt2 = new BigInteger(1, hashDigest);
117                //BigInteger testBigInt = new BigInteger( Hashfunction.generateHashDigest(Datablock.getInstance().Message, Datablock.getInstance().HashFunctionIdent) );
118                //string testHashDigest = testBigInt.ToString(16);
119                //string testHashDigest2 = testBigInt2.ToString(16);
120
121                BigInteger H = new BigInteger(1, Hashfunction.generateHashDigest(Datablock.getInstance().Message, Datablock.getInstance().HashFunctionIdent));
122                BigInteger helpSubst = T.Multiply(BigInteger.Two.Pow(hashDigestLength)).Add(H); // Datablock erstellen; T=HashFuncIdent; H=HashDigest
123                //string test = helpSubst.ToString(16);
124                a = (BigInteger.Two.Pow(datablocklength)).Subtract(helpSubst); // a = 2^288- (helpsubst); muss div by three sein
125
126                if (0 == (a.Mod(BigInteger.Three)).IntValue)
127                {
128                    isDivByThree = true;
129                }
130                else
131                {
132                    Datablock.getInstance().Message = Datablock.getInstance().Message + " ";
133                }
134            }
135            // s = 2^1019-a/3*2^34
136            // 1019 ist fix wenn Modulus 3072 lang ist
137            BigInteger fakedSignature = (BigInteger.Two.Pow(1019)).Subtract(a.Divide(BigInteger.Three).Multiply(BigInteger.Two.Pow(34)));
138            //string test2 = fakedSignature.ToString(16);
139
140            byte[] returnByteArray = new byte[this.m_KeyLength / 8]; // KeyLength is in bit
141            Array.Copy(fakedSignature.ToByteArray(), 0, returnByteArray, returnByteArray.Length - fakedSignature.ToByteArray().Length, fakedSignature.ToByteArray().Length);
142
143            this.m_Signature = returnByteArray;
144            this.m_bSigGenerated = true;
145            this.OnRaiseSigGenEvent(SignatureType.Bleichenbacher);
146
147            //this.generateSignature2();
148        }
149
150        public void GenerateSignature3()
151        {
152            this.m_KeyLength = RSAKeyManager.getInstance().RsaKeySize;
153
154            int hashDigestLength = Hashfunction.getDigestSize() * 8; // weil Size in Byte zurückgegeben wird
155            int hashIdentLength = Datablock.getInstance().HashFunctionIdent.DERIdent.Length * 4; // weil ein zeichen im string = 4 bit           
156            BigInteger derIdent = new BigInteger(Datablock.getInstance().HashFunctionIdent.DERIdent, 16);
157
158            BigInteger datablockLength = BigInteger.ValueOf(hashDigestLength + hashIdentLength + 8); // Länge Datenblock inkl 0-Byte (=8Bit)
159            bool isDivByThree = false;
160            BigInteger N = null;
161
162            while (false == isDivByThree)
163            {
164                BigInteger hashDigest = new BigInteger(1, Hashfunction.generateHashDigest(Datablock.getInstance().Message, Datablock.getInstance().HashFunctionIdent));
165                BigInteger D = derIdent.Multiply(BigInteger.Two.Pow(hashDigestLength)).Add(hashDigest); // Datablock erstellen; T=HashFuncIdent; H=HashDigest
166                N = (BigInteger.Two.Pow(datablockLength.IntValue)).Subtract(D); // N muss vielfaches von 3 sein
167
168                if (0 == (N.Mod(BigInteger.Three)).IntValue)
169                {
170                    isDivByThree = true;
171                }
172                else
173                {
174                    Datablock.getInstance().Message = Datablock.getInstance().Message + " ";
175                }
176            }
177            BigInteger x = BigInteger.ValueOf(this.m_KeyLength - 15); // 15 weil die ersten 15 bit 0 sind
178            BigInteger startPos = BigInteger.ValueOf(2072); // durch Eingabe ersetzen
179            BigInteger endPos = startPos.Add(datablockLength);
180
181            ///////// nicht zur Berechnung nötig
182            BigInteger lengthDivThree = x.Divide(BigInteger.Three);
183            BigInteger beta = endPos.Subtract(BigInteger.Two.Multiply(lengthDivThree)).Subtract(datablockLength); // sollte 34 sein
184            //////////
185
186            //BigInteger garbage = (N.Pow(2).Multiply(
187            //BigInteger fakeSig = BigInteger.Two.Pow(this.m_KeyLength).Subtract(N.Multiply(BigInteger.Two.Pow(startPos)));
188            BigInteger A = BigInteger.Two.Pow(lengthDivThree.IntValue);
189            BigInteger B = (N.Multiply(BigInteger.Two.Pow(beta.IntValue)).Divide(BigInteger.Three));
190
191            BigInteger fakeSig = A.Pow(3).Subtract((BigInteger.Three.Multiply((A.Pow(2))).Multiply(B))).Add((BigInteger.Three.Multiply(A.Multiply((B.Pow(2)))))).Subtract((B.Pow(3)));
192            string test = fakeSig.ToString(16);
193            BigInteger fakeSigResult = MathFunctions.cuberoot(fakeSig);
194
195
196            byte[] returnByteArray = new byte[this.m_KeyLength / 8]; // KeyLength is in bit
197            Array.Copy(fakeSigResult.ToByteArray(), 0, returnByteArray, returnByteArray.Length - fakeSigResult.ToByteArray().Length, fakeSigResult.ToByteArray().Length);
198
199            this.m_Signature = returnByteArray;
200            this.m_bSigGenerated = true;
201            this.OnRaiseSigGenEvent(SignatureType.Bleichenbacher);
202        }
203        */
204
205        public event GuiLogHandler OnGuiLogMsgSend;
206
207        public void registerHandOff()
208        {
209            GuiLogMsgHandOff.getInstance().registerAt(ref OnGuiLogMsgSend);
210        }
211
212        public void SendGuiLogMsg(string message, Cryptool.PluginBase.NotificationLevel logLevel)
213        {
214            if (null != OnGuiLogMsgSend)
215            {
216                OnGuiLogMsgSend(message, logLevel);
217            }
218        }
219    }
220}
Note: See TracBrowser for help on using the repository browser.