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

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

added english menus
changed GUI a bit
added additional input for bleichenbacher signatures

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