source: trunk/CrypPlugins/PKCS1/Library/BleichenbacherSig.cs @ 1778

Last change on this file since 1778 was 1778, checked in by schomburg, 11 years ago

renamed some classes for the sake of consistency

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