SHA1 с BASE64 в классе утилит Java не генерирует правильный пароль - PullRequest
3 голосов
/ 27 января 2011

Я написал класс утилит в Java для вызова веб-сервиса.Мой класс утилит создает дайджест пароля, необходимый для вызова веб-службы.Этот дайджест-пароль состоит из: Дайджест-пароля, сгенерированного по следующему алгоритму: base64Encode(sha1Hash(<Nonce><TimeStamp><Secret>))

Мой сгенерированный пароль не равен сгенерированному паролю из инструмента поставщика, который использует тот же алгоритмиметь доступ к их коду, поэтому я не уверен, как это реализовано).Я не уверен, что я сделал что-то не так, может кто-нибудь просмотреть мой код и посмотреть, сделал ли я что-то не так с шифрованием SHA1 или с кодировкой Base64.Спасибо за вашу помощь!Ниже мой код:

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.UUID;

import javax.xml.bind.DatatypeConverter;
import org.apache.commons.codec.binary.Base64;

public class OminitureWSUtil {

private static MessageDigest SHA1;

static {
    try {
        SHA1 = MessageDigest.getInstance("SHA1");

    } catch(NoSuchAlgorithmException nae) {
        throw new RuntimeException(nae);
    }
}

static class OmniturePasswordDigest {
    private final String timestamp;
    private final String nonce;
    private final String secret;

    private String password;

    public OmniturePasswordDigest(String secret) {
        Calendar c = GregorianCalendar.getInstance(TimeZone.getTimeZone("GMT+0"));
        c.setTime(new Date());

        //timestamp =  DatatypeConverter.printDateTime(c);
        //nonce = UUID.randomUUID().toString().replace("-", "");

        timestamp = "2011-01-26T20:10:56Z";
        nonce = "MTkyMTYwZWMzMjIzZGJmYzNiYmE5M2E5";

        this.secret = secret;
    }

    public String getTimestamp() {
        return timestamp;
    }

    public String getNonce() {
        return nonce;
    }

    public String generatePassword() {
        if(password == null) {
            String beforeEncryption = nonce+timestamp+secret;
            System.out.println("before encryption, encoding: " + beforeEncryption);

            try {
                SHA1.reset();
                byte[] toEncrypt = beforeEncryption.getBytes("UTF-8");
                //SHA1.update(toEncrypt, 0, toEncrypt.length);
                SHA1.update(beforeEncryption.getBytes());
            } catch (UnsupportedEncodingException uee) {
                throw new RuntimeException(uee);
            }

            byte[] encryptedRaw = SHA1.digest();
            byte[] encoded = Base64.encodeBase64(encryptedRaw);

            try {
                password = new String(encoded, "UTF-8");
            } catch (UnsupportedEncodingException uee) {
                throw new RuntimeException(uee);
            }
        }

        return password;
    }
}


public static OmniturePasswordDigest generatePasswordDigest(String secret) {
    return new OmniturePasswordDigest(secret);
}

public static void main(String[] args) {
    OmniturePasswordDigest opd = generatePasswordDigest("1779ab07fb93a01e3d4a6ee174124b91");
    System.out.println("nonce: " + opd.getNonce());
    System.out.println("timestamp: " + opd.getTimestamp());
    System.out.println("password: " + opd.generatePassword());

    if("Lr+m+/6y3XUxvjd8Rtn75gqn/b4=".equals(opd.generatePassword())) {
        System.out.println("all good");
    } else {
        System.out.println("generated password is not the same, it should be: " + 
                "Lr+m+/6y3XUxvjd8Rtn75gqn/b4=");
    }

}

}

Ответы [ 2 ]

2 голосов
/ 27 января 2011

Гонка SHA1 видна за много миль.Измените код следующим образом:

-SHA1.reset();
+MessageDigest SHA1= (MessageDigest) OminitureWSUtil.SHA1.clone();

Сброс - это не то, что вам нужно;Клон предназначен для таких случаев.

btw, бросая любое исключение в классе init (static {}), убивает класс и частично любой другой класс, ссылающийся на этот класс (то есть все приложение [web]).Это плохая практика, поскольку исключение (java.lang.ExceptionInInitializerError) может где-то попасть в ловушку.

0 голосов
/ 27 января 2011

Полагаю, это для REST Api для Omniture? На этом сайте есть рабочий пример. Тем не менее, ваш код выглядит правильно на первый взгляд.

https://developer.omniture.com/java_rest_api

Также я не знаю, как вы собираетесь использовать этот класс, но SHA1 не является потокобезопасным, и если несколько вызовов вызывает generatePassword (), вы получите неожиданное поведение.

...