KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > snow > crypto > PasswordSearchDialog


1 package snow.crypto;
2
3 import java.awt.Insets JavaDoc;
4 import javax.swing.*;
5 import javax.swing.event.*;
6 import javax.swing.border.*;
7 import java.awt.BorderLayout JavaDoc;
8 import java.awt.Dimension JavaDoc;
9 import java.awt.EventQueue JavaDoc;
10 import java.awt.Color JavaDoc;
11 import java.awt.event.*;
12 import java.util.*;
13 import java.math.*;
14 import java.text.*;
15 import snow.utils.storage.FileUtils;
16 import snow.utils.gui.*;
17 import sun.misc.BASE64Encoder;
18
19 import java.security.*;
20 import java.security.spec.*;
21 import javax.crypto.spec.*;
22 import javax.crypto.*;
23 import java.io.*;
24 import SnowMailClient.crypto.Utilities;
25 import SnowMailClient.crypto.FileCipherManager;
26
27
28 /** class PasswordSearchDialog.
29    try to find the passphrase using brute force and dictionary attack.
30    A lot more could be done, for example
31      1) Multithreaded code
32      2) distributed code over some network of computers
33      3) pattern random search (voyel-letter-number-number)
34      4) prepend some numbers 1-100 (either small numbers)
35      5) try the yahoo stupid passes like "aplechicken33", ...
36      6) prepend some date 1970-2006
37
38 */

39 public final class PasswordSearchDialog extends JDialog
40 {
41    final JPasswordField passwordToAnalyse = new JPasswordField(20);
42    final JTextField knownPrefixField = new JTextField(6);
43    final JTextField knownSuffixField = new JTextField(6);
44    final private JSpinner minPassLength = new JSpinner();
45    final private JSpinner maxPassLength = new JSpinner();
46    final private JTextArea charsToTry = new JTextArea(
47       "ABCDEFGHIJKLMNOPQRSTUCVWXYZ abcdefghijklmnopqrstuvwxyz1234567890+-*/_$!?\\=.,:;%&()[]{}#üöäïéàèûôî", 3,30);
48    final private NumberFormat df = DecimalFormat.getInstance();
49
50    final private FileField dictsFolder = new FileField("e:/java/dics/", false,
51        "Choose the folder or files where the dicts are",
52        JFileChooser.FILES_AND_DIRECTORIES);
53    final private JCheckBox tryStartOfPhrases = new JCheckBox("Try startings of words", true);
54    final private JSpinner minDictPassLength = new JSpinner();
55
56    byte[] trueHashOfPass;
57
58    String JavaDoc knownPrefix = null;
59    String JavaDoc knownSuffix = null;
60    final File fileToDecipher;
61
62    /** @param fileToDecipher if non null, the found password will also be used to decipher the file,
63    * to test if it is correct.
64    */

65    public PasswordSearchDialog(final JDialog parent, final byte[] trueHashOfPass_, File fileToDecipher)
66    {
67       super(parent, "Snowmail password crack tool", true);
68
69       this.trueHashOfPass = trueHashOfPass_;
70       this.fileToDecipher = fileToDecipher;
71
72       JTextArea explain = new JTextArea(
73            "This utility will try to discover the snowmail password."
74         +"\nSnowmail password is made of the 16 first bytes of the sha-1 hash of the passphrase provided."
75         +"\nThe four first bytes of the hash of the hash are stored to allow quick password verification."
76         +"\nSha-1 hashes are not reversible. So, only dictionary and brute force tries are possible"
77         +"\nto find out the passphrase"
78         +"\n\nYou will be afraid how \"easy\" bad passwords are cracked quickly, even long ones."
79         +"\nThis will help you choosing good passwords, i.e. longer than 8 chars, with special"
80         +"\nchars and numbers. They will resist millions of years."
81
82         +"\n\nFor dictionary attack, you have to provide a folder, all words in all files (recursively),"
83         +"\nlonger than 4 chars will be tested."
84         +"\nUse for example all the free available dictionnaries from OpenOffice (in all languages !)"
85         +"\nand some files containing the most common passwords. Include some recent newspaper as well."
86         +"\n\nLook at http://en.wikipedia.org/wiki/Password_cracking to learn more");
87       explain.setBorder(new EmptyBorder(5,5,5,5));
88       explain.setBackground(UIManager.getColor("Panel.background"));
89       explain.setEditable(false);
90       add(explain, BorderLayout.NORTH);
91
92       JPanel input = new JPanel();
93       GridLayout3 gl = new GridLayout3(2,input);
94       add(input, BorderLayout.CENTER);
95
96       if(trueHashOfPass==null)
97       {
98          gl.add("Password to test");
99          gl.add(passwordToAnalyse);
100          gl.addSeparator();
101       }
102       else
103       {
104         /* gl.add("Password hash ID =");
105          gl.add(Utilities.encodeBase64(trueHashOfPass));
106          gl.addSeparator();*/

107       }
108
109       gl.addTitleSeparator("Eventual knowledge");
110       gl.add("Known prefix");
111       gl.add(knownPrefixField);
112       gl.add("Known suffix");
113       gl.add(knownSuffixField);
114
115       gl.addTitleSeparator("Brute force attack");
116       gl.add("Alphabet (chars to try)");
117       gl.add(charsToTry);
118       charsToTry.setLineWrap(true);
119       gl.addSeparator();
120       gl.add("Min password length");
121       gl.add(minPassLength);
122       minPassLength.setPreferredSize(new Dimension JavaDoc(50, (int) minPassLength.getPreferredSize().getHeight()));
123       minPassLength.setValue(0);
124       gl.add("Max password length");
125       gl.add(maxPassLength);
126       maxPassLength.setPreferredSize(new Dimension JavaDoc(50, (int) maxPassLength.getPreferredSize().getHeight()));
127       maxPassLength.setValue(6);
128
129
130       gl.addTitleSeparator("Dictionary attack");
131       gl.add("Dictionaries (recurse)");
132       gl.add(dictsFolder);
133       dictsFolder.setComponentWidth(200);
134       gl.add("");
135       gl.add(tryStartOfPhrases);
136       gl.add("min word length");
137       gl.add(minDictPassLength);
138       minDictPassLength.setValue(5);
139
140       JPanel controlPanel = new JPanel();
141       add(controlPanel, BorderLayout.SOUTH);
142       JButton close = new JButton("Close",Icons.CrossIcon.shared10);
143       close.setMargin(new Insets JavaDoc(0,1,0,1));
144       close.setFocusPainted(false);
145       controlPanel.add(close);
146       close.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae)
147       {
148          setVisible(false);
149          dispose();
150       }});
151
152       JButton go = new JButton("Crack", Icons.WizIcon.shared15);
153       go.setMargin(new Insets JavaDoc(0,1,0,1));
154       go.setFocusPainted(false);
155       go.setBackground(Color.orange);
156       controlPanel.add(go);
157       go.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae)
158       {
159          cancel = false;
160          found = false;
161          if(trueHashOfPass_==null)
162          {
163            // zero length pass are also pass !
164
char[] pass = passwordToAnalyse.getPassword();
165            trueHashOfPass = hashPassword_ID(new String JavaDoc(pass));
166          }
167
168          if(knownPrefixField.getText().length()>0)
169          {
170             knownPrefix = knownPrefixField.getText();
171          }
172          else
173          {
174             knownPrefix = null;
175          }
176
177          if(knownSuffixField.getText().length()>0)
178          {
179             knownSuffix = knownSuffixField.getText();
180          }
181          else
182          {
183             knownSuffix = null;
184          }
185
186          try
187          {
188            if(dictsFolder.getPath()!=null)
189            {
190               List<File> files = new ArrayList<File>();
191               FileUtils.getAllFilesRecurse(dictsFolder.getPath(), files);
192               // todo: ignore ".zip" files ! of go into !
193
if(files.size()>0)
194               {
195                 analyseFiles(files, (Integer JavaDoc) minDictPassLength.getValue());
196               }
197
198               if(found) return;
199            }
200          } catch(Exception JavaDoc e) { e.printStackTrace(); }
201
202          if(cancel) return;
203
204          analyse((Integer JavaDoc) minPassLength.getValue(), (Integer JavaDoc) maxPassLength.getValue(), charsToTry.getText());
205       } });
206
207       pack();
208       setLocationRelativeTo(null);
209       setVisible(true);
210    }
211
212
213    private void analyseFiles(final List<File> files, final int minDictPassLength)
214    {
215        final JDialog d = new JDialog(this, "Password Search from dictionaries ("+files.size()+")", true);
216
217        final JProgressBar progress = new JProgressBar();
218        d.add(progress, BorderLayout.NORTH);
219        progress.setStringPainted(true);
220
221        JPanel center = new JPanel();
222        GridLayout3 gl = new GridLayout3(1,center);
223        d.add(center, BorderLayout.CENTER);
224        gl.add("Number of files to use: "+files.size());
225        long totSize = 0;
226        for(File f: files) totSize+=f.length();
227        gl.add("Total size: " + (int)(totSize/1e6)+" MB");
228
229        JPanel controlPanel = new JPanel();
230        d.add(controlPanel, BorderLayout.SOUTH);
231        JButton stop = new JButton("Cancel");
232        controlPanel.add(stop);
233        stop.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) {
234           cancel = true;
235        } });
236
237        Thread JavaDoc t = new Thread JavaDoc()
238        {
239             public void run()
240             {
241                for(int i=0; i<files.size(); i++)
242                {
243                  progress.setValue( (int)(i*100.0/files.size()));
244                  progress.setString( files.get(i).getName() );
245
246                  String JavaDoc res = searchInFile(files.get(i), minDictPassLength, 55);
247                  if(res!=null)
248                  {
249                     break;
250                  }
251                  else if(cancel)
252                  {
253                     JOptionPane.showMessageDialog(d, "Cancelled");
254                     break;
255                  }
256                }
257
258                d.setVisible(false);
259                d.dispose();
260             }
261        };
262        t.start();
263
264        d.setSize(400,300);
265        d.setLocationRelativeTo(null);
266        d.setVisible(true);
267    }
268
269    private String JavaDoc searchInFile(File f, int minLength, int maxLength)
270    {
271       long fileWordsAnalysed = 0;
272       BufferedReader in = null;
273       try
274       {
275          in = new BufferedReader(new FileReader(f));
276          String JavaDoc line;
277          while((line=in.readLine())!=null)
278          {
279             // stupid tokenizer
280
StringTokenizer st = new StringTokenizer(line, " |()/"); // good delimiters for OOO dics, affix and other files
281
while(st.hasMoreElements())
282             {
283                String JavaDoc w = st.nextToken();
284
285                if(found) return null; // stop this search, was found otherwise, maybe by another thread
286
if(cancel) return null;
287
288                // ignore short words, they can be find out with systematic search !!
289
if(w.length()<minLength) continue;
290                if(w.length()>maxLength) continue; // ignore long pass !
291

292
293                fileWordsAnalysed++;
294
295                if(Math.random()<0.00001)
296                {
297                   System.out.println("file word: "+w);
298                }
299
300                if(tryPass(w)!=null) // quick
301
{
302                   System.out.println("Found in "+f);
303                   found = true;
304                   return createPass(w);
305                }
306
307                // try variants (first letters only), combinations, ...
308

309                // VARIANT 1: change first letter case
310
String JavaDoc w2 = null;
311                if(Character.isUpperCase(w.charAt(0)))
312                {
313                   w2 = ""+Character.toLowerCase(w.charAt(0))+ w.substring(1);
314                }
315                else if(Character.isLowerCase(w.charAt(0)))
316                {
317                   w2 = ""+Character.toUpperCase(w.charAt(0))+ w.substring(1);
318                }
319
320                if(w2!=null)
321                {
322                   if(tryPass(w2)!=null)
323                   {
324                      System.out.println("Found in "+f);
325                      found = true;
326                      return createPass(w2);
327                   }
328                }
329
330                // VARIANT 2: try first letters (but at least 5)
331
if(this.tryStartOfPhrases.isSelected())
332                {
333                   for(int i=w.length()-1; i>=minLength-1; i--)
334                   {
335                      String JavaDoc w3 = w.substring(0, i-1);
336                      if(tryPass(w3)!=null)
337                      {
338                         System.out.println("Found in "+f);
339                         found = true;
340                         return createPass(w3);
341                      }
342                   }
343                }
344             }
345
346
347          }
348       }
349       catch(Exception JavaDoc e)
350       {
351          e.printStackTrace();
352       }
353       finally
354       {
355          FileUtils.closeIgnoringExceptions( in );
356       }
357       System.out.println(""+fileWordsAnalysed+" words analysed in "+f);
358       return null; // not found
359
}
360
361    /** null if not equal, some dummy string of so.
362    * null string is quicker than boolean return !
363    */

364    private String JavaDoc equals(byte[] tryHash, byte[] refHash)
365    {
366       for(int i=0; i<refHash.length; i++)
367       {
368          if(tryHash[i]!=refHash[i]) return null;
369       }
370       return "yeah";
371
372       // slow return Arrays.equals(tryHash, refHash);
373
}
374
375    /** on sign match, also try to decipher the file, if fileToDecipher is non null !
376    */

377    private String JavaDoc tryPass(String JavaDoc w) // return null is quicker than boolean !
378
{
379      if(equals(hashPassword_ID(createPass(w)), trueHashOfPass)!=null)
380      {
381         if(this.fileToDecipher!=null)
382         {
383            try
384            {
385               FileCipherManager.decipherVectorFromFile(fileToDecipher,
386                  SecretKeyUtilities.generateSecretKeyFromPassphrase( createPass(w).getBytes(), 16 ));
387            }
388            catch(Exception JavaDoc e)
389            {
390               System.out.println("Bad pass: "+createPass(w));
391               return null;
392            }
393         }
394
395         if(fileToDecipher==null)
396         {
397           int res = JOptionPane.showConfirmDialog(this, "The password may be: \""+createPass(w)+"\"",
398                       "A Password was found that has the same signature", JOptionPane.YES_NO_CANCEL_OPTION);
399           if(res==JOptionPane.CANCEL_OPTION)
400           {
401              cancel=true;
402              return null;
403           }
404           if(res!=JOptionPane.YES_OPTION) return null;
405         }
406         else
407         {
408           JOptionPane.showMessageDialog(this, "The password is: \""+createPass(w)+"\"");
409         }
410
411         found = true;
412         return createPass(w);
413      }
414      else
415      {
416         return null;
417      }
418    }
419
420    /** puts suffix and prefixes
421    */

422    private String JavaDoc createPass(String JavaDoc p)
423    {
424       if(knownPrefix==null && knownSuffix==null) return p;
425       StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
426       if(knownPrefix!=null) sb.append(knownPrefix);
427       sb.append(p);
428       if(knownSuffix!=null) sb.append(knownSuffix);
429       return sb.toString();
430    }
431
432
433    BigInteger numberAnalysedSoFar = BigInteger.ZERO;
434    BigInteger numberToAnalyse = null;
435    long startTime = 0;
436    boolean cancel = false;
437    boolean found = false;
438    final private JLabel soFarLabel = new JLabel("So far: 0 ");
439    final private JLabel remainingTimeLabel = new JLabel("Time remaining: ?");
440    final private JLabel performanceLabel = new JLabel("Performance: ?");
441
442
443    private void analyse(final int passMinLength, final int passMaxLength, final String JavaDoc charsToTry)
444    {
445          final JDialog d = new JDialog(this, "Password Search", true);
446
447          final JProgressBar progress = new JProgressBar();
448          d.add(progress, BorderLayout.NORTH);
449          progress.setStringPainted(true);
450
451          JPanel center = new JPanel();
452          GridLayout3 gl = new GridLayout3(1,center);
453          d.add(center, BorderLayout.CENTER);
454          gl.add("Alphabet size used: "+charsToTry.length());
455          gl.add("Password length considered: "+passMinLength+" .. "+passMaxLength);
456          numberToAnalyse = calcNumberOfPossibilities(passMinLength, passMaxLength,charsToTry.length());
457          String JavaDoc bi=df.format(numberToAnalyse);
458          gl.add("Number of possibilities: "+bi);
459
460          gl.addSeparator();
461          gl.add(soFarLabel);
462          soFarLabel.setText("");
463          gl.add(remainingTimeLabel);
464          remainingTimeLabel.setText("");
465
466          gl.addSeparator();
467          gl.add(performanceLabel);
468          performanceLabel.setText("");
469
470          System.out.println("Alphabet size: "+charsToTry.length());
471          System.out.println("Number of possibilities: "+numberToAnalyse);
472
473          JPanel controlPanel = new JPanel();
474          d.add(controlPanel, BorderLayout.SOUTH);
475          JButton stop = new JButton("Cancel");
476          controlPanel.add(stop);
477          stop.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) {
478             cancel = true;
479          } });
480
481
482          Thread JavaDoc t = new Thread JavaDoc()
483          {
484             public void run()
485             {
486                String JavaDoc res = searchSystematically(passMinLength, passMaxLength, charsToTry, progress);
487                d.setVisible(false);
488                d.dispose();
489                if(cancel)
490                {
491                   JOptionPane.showMessageDialog(d, "Cancelled");
492                }
493                else if(res==null)
494                {
495                   JOptionPane.showMessageDialog(d, "The password was not found, try more chars and more alphabet.");
496                }
497             }
498          };
499          t.start();
500
501          d.setSize(400,300);
502          d.setLocationRelativeTo(null);
503          d.setVisible(true);
504
505    }
506
507
508    private String JavaDoc searchSystematically(final int passMinLength, final int passMaxLength, final String JavaDoc charsToTry, final JProgressBar progress)
509    {
510       startTime = System.currentTimeMillis();
511       numberAnalysedSoFar = BigInteger.ZERO;
512
513       for(int i=passMinLength; i<=passMaxLength; i++)
514       {
515          String JavaDoc found = searchSystematicallyExactLength(i, charsToTry, progress);
516          if(found!=null) return found;
517       }
518       return null;
519    }
520
521
522    /** @return non null if found !
523    * search all password
524    */

525    private String JavaDoc searchSystematicallyExactLength(final int passLength, final String JavaDoc charsToTry, final JProgressBar progress)
526    {
527       System.out.println("Searching all passwords of length "+passLength+", poss = "+Math.pow(charsToTry.length(), passLength));
528
529       long lastUpdate = 0;
530
531       // all these indices will be updated from 0 (now) up to passMaxLength until all are at passMaxLength
532
// one can see this as a big number on base passMaxLength
533
int[] pos = new int[passLength];
534       int n = charsToTry.length();
535
536       long cnt = 0;
537       while(true)
538       {
539          numberAnalysedSoFar = numberAnalysedSoFar.add(BigInteger.ONE);
540          cnt++;
541          final StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
542          for(int p : pos)
543          {
544             sb.append( charsToTry.charAt(p) );
545          }
546          //System.out.println("pass? "+sb);
547
if(tryPass(sb.toString())!=null)
548          {
549             found = true;
550             return createPass(sb.toString());
551          }
552
553          if(increment(pos, n)==-1)
554          {
555            System.out.println(""+cnt);
556            return null;
557          }
558
559          if(cancel) return null;
560
561          if(System.currentTimeMillis() - lastUpdate>1000) // update only each second => no seek performance loss.
562
{
563             lastUpdate = System.currentTimeMillis();
564             try
565             {
566               EventQueue.invokeAndWait(new Runnable JavaDoc() { public void run() {
567                 progress.setString( ""+sb.toString());
568                 soFarLabel.setText("Analysed so far: "+df.format(numberAnalysedSoFar));
569                 int prog = numberAnalysedSoFar.multiply(BigInteger.valueOf(100)).divide(numberToAnalyse).intValue();
570
571                 //System.out.println(""+prog+"% for "+numberAnalysedSoFar+" / "+numberToAnalyse );
572
long millisSoFar = System.currentTimeMillis() - startTime;
573                 if(millisSoFar>1000)
574                 {
575                    // we have secs for numberAnalysedSoFar, how many for numberToAnalyse
576
BigInteger totTimeMillis = numberToAnalyse.divide(numberAnalysedSoFar).multiply(BigInteger.valueOf(millisSoFar));
577                    BigInteger secsRemaining = totTimeMillis.subtract( BigInteger.valueOf(millisSoFar) );
578                    remainingTimeLabel.setText( "Remaining time = "+getTime(secsRemaining.divide(BigInteger.valueOf(1000)))) ;
579
580                    performanceLabel.setText( "Performance: "
581                     + df.format(numberAnalysedSoFar.multiply(BigInteger.valueOf(1000)).divide( BigInteger.valueOf(millisSoFar)))
582                     +" password per sec");
583                 }
584
585                 progress.setValue( prog );
586               }});
587             } catch(Exception JavaDoc e){}
588          }
589       }
590
591
592    }
593
594    private static String JavaDoc getTime(BigInteger secs)
595    {
596       // would be efficienter to look first if small...
597
// but is not called often, only each 1000 ms...
598

599       if(secs.compareTo(BigInteger.valueOf(3600L*24*365*1000000000*2))>0) // be careful, 1/100 of max Long !
600
{
601          BigInteger[] dr = secs.divideAndRemainder(BigInteger.valueOf(3600L*24*365*1000000000));
602          return ""+dr[0]+" billions of years";
603       }
604
605       if(secs.compareTo(BigInteger.valueOf(3600L*24*365*1000000*2))>0)
606       {
607          BigInteger[] dr = secs.divideAndRemainder(BigInteger.valueOf(3600L*24*365*1000000));
608          return ""+dr[0]+" milions of years";
609       }
610
611       if(secs.compareTo(BigInteger.valueOf(3600L*24*365*1000))>0)
612       {
613          BigInteger[] dr = secs.divideAndRemainder(BigInteger.valueOf(3600L*24*365*100));
614          return ""+dr[0]+" centuries";
615       }
616
617       if(secs.compareTo(BigInteger.valueOf(3600L*24*365*2))>0)
618       {
619          BigInteger[] dr = secs.divideAndRemainder(BigInteger.valueOf(3600L*24*365));
620          if(dr[0].compareTo(BigInteger.valueOf(3600L*24*365*5))>0) // don't forget the L !!!
621
{
622             return ""+dr[0]+" years";
623          }
624          else
625          {
626             return ""+dr[0]+" years "+getTime(dr[1]);
627          }
628       }
629       if(secs.compareTo(BigInteger.valueOf(3600*48))>0)
630       {
631          BigInteger[] dr = secs.divideAndRemainder(BigInteger.valueOf(3600*24));
632          if(dr[0].compareTo(BigInteger.valueOf(3600*24*5))>0)
633          {
634             return ""+dr[0]+" days";
635          }
636          else
637          {
638             return ""+dr[0]+" days "+getTime(dr[1]);
639          }
640
641       }
642       if(secs.compareTo(BigInteger.valueOf(3600*2))>0)
643       {
644          return ""+secs.divide(BigInteger.valueOf(3600))+" h";
645       }
646       if(secs.compareTo(BigInteger.valueOf(60*2))>0)
647       {
648          return ""+secs.divide(BigInteger.valueOf(60))+" min";
649       }
650       return ""+secs+" s";
651    }
652
653    /** @return -1 when all numbers are equal to n, otherwise the index where digit changed
654    */

655    private static int increment(int[] nb, int n)
656    {
657       // nb is a big number in base n
658
// [0,0,0]++ => [0,0,1] [0,0,n-1]=> [0,1,0], ...
659
int add = 0;
660       for(int i=nb.length-1; i>=0; i--)
661       {
662          if(nb[i]<n-1)
663          {
664             nb[i]++;
665             return i;
666          }
667          else
668          {
669             nb[i]=0;
670             // pass to next digit
671
}
672       }
673
674       return -1;
675    }
676
677    private static String JavaDoc genRandomPass( final String JavaDoc charsToTry, int len)
678    {
679       StringBuffer JavaDoc pass = new StringBuffer JavaDoc();
680       for(int i=0; i<len; i++)
681       {
682          pass.append( charsToTry.charAt( (int)( Math.random()*charsToTry.length()) ));
683       }
684       return pass.toString();
685    }
686
687    public static BigInteger calcNumberOfPossibilities(int minLen, int maxLen, int chars)
688    {
689       BigInteger bi = new BigInteger("0");
690       for(int i=minLen; i<=maxLen; i++)
691       {
692         bi = bi.add( new BigInteger(""+chars).pow(i) );
693       }
694       return bi;
695    }
696
697
698    static MessageDigest md = null;
699    static
700    {
701        try
702        {
703           md = MessageDigest.getInstance("SHA1");
704        }
705        catch(Exception JavaDoc e)
706        {
707           e.printStackTrace();
708        }
709    }
710
711    /** quick sun impl.
712    *
713    public static byte[] hashPassword(String input)
714    {
715        try
716        {
717           md.reset();
718           return md.digest(input.getBytes());
719        }
720        catch(Exception e)
721        {
722           throw new RuntimeException(""+e.getMessage());
723        }
724    }*/

725
726    /** the password is the digest of the phrase, the id is the 4 first bytes of the digest if the password
727    */

728    static byte[] intermetiateDigest = null;
729    static byte[] intermetiateDigest2 = new byte[16];
730    public static byte[] hashPassword_ID(String JavaDoc passphrase)
731    {
732        try
733        {
734           md.reset();
735           intermetiateDigest = md.digest(passphrase.getBytes());
736           System.arraycopy(intermetiateDigest, 0, intermetiateDigest2, 0, 16);
737           return md.digest(intermetiateDigest2);
738           //return md.digest();
739
/*byte[] ret = new byte[4];
740           System.arraycopy(intermetiateDigest, 0, ret, 0, 4);
741           return ret;*/

742        }
743        catch(Exception JavaDoc e)
744        {
745           throw new RuntimeException JavaDoc(""+e.getMessage());
746        }
747    }
748
749
750    public static void main(String JavaDoc[] args)
751    {
752       new PasswordSearchDialog(new JDialog(), null, null);
753    }
754
755 }
Popular Tags