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

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