2016-09-08 2 views
0

Я написал класс, который должен подписать и base64 строку текста, используя закрытый ключ на сервере, а затем вернуть подпись. Он генерирует другую подпись каждый раз, когда она запускается для одного и того же текста. Зачем это делать? Я проверил, что это подпись, которая меняется, а не проблема с преобразованием base64, временно отключив преобразование на моем тестовом компьютере.Подписание строки Java с использованием Signature.sign: почему подпись всегда различна?

Мой код:

public class SigningPIP implements SigningPIPInterface { 
private static final String SIGNING_ALGORITHM = "SHA1withDSA"; 

/** 
* Provides a signature for a stringified JSON license 
* @param license stringified JSON license to be used for signature generation 
* @param keystoreFilePath The file path where the keystore can be found 
* @param keystorePassword The password to the keystore 
* @param privateKeyAlias The alias of the private key in the keystore to be used for signing 
* @param privateKeyPassword The password for the private key to be used for signing 
* @return Properties object containing the base64 encoded signature, algorithm used and certificate DN 
*/ 
@Override 
public Properties getLicenseSignature(String license, String keystoreFilePath, String keystorePassword, String privateKeyAlias, String privateKeyPassword) { 
    PrivateKey privateKey = getPrivateKey(keystoreFilePath, keystorePassword, privateKeyAlias, privateKeyPassword); 

    Properties licenseSignature = new Properties(); 
    licenseSignature.setProperty("sig_algorithm", SIGNING_ALGORITHM); 
    licenseSignature.setProperty("cert_DN", getCertificateIssuerDN(keystoreFilePath, keystorePassword, privateKeyAlias)); 

    byte[] licenseByteArray = license.getBytes(); 
    System.out.println(new String(licenseByteArray)); 
    try { 
     Signature dsa = Signature.getInstance(SIGNING_ALGORITHM); 
     dsa.initSign(privateKey); 
     dsa.update(licenseByteArray); 
     byte[] signature = dsa.sign(); 
     licenseSignature.setProperty("signature_base64", DatatypeConverter.printBase64Binary(signature)); 
    } 
    catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) { 
     //TODO: Add logging 
    } 
    return licenseSignature; 
} 

/** 
* Pulls the private key from the specified keystore 
* @param keystoreFilePath The file path where the keystore can be found 
* @param keystorePassword The password to the keystore 
* @param privateKeyAlias The alias of the private key in the keystore 
* @param privateKeyPassword The password for the private key in the keystore 
* @return The specified private key from the keystore 
*/ 
private PrivateKey getPrivateKey(String keystoreFilePath, String keystorePassword, String privateKeyAlias, String privateKeyPassword) { 
    try { 
     FileInputStream keyStoreFile = new FileInputStream(keystoreFilePath); 
     KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
     keyStore.load(keyStoreFile, keystorePassword.toCharArray()); 
     return (PrivateKey)keyStore.getKey(privateKeyAlias, privateKeyPassword.toCharArray()); 
    } 
    catch(KeyStoreException | NoSuchAlgorithmException | IOException | CertificateException | UnrecoverableKeyException e) { 
     //TODO: Add logging; 
    } 
    return null; 
} 

/** 
* Pulls the Issuer DN from a keystore for the specified private key 
* @param keystoreFilePath The file path where the keystore can be found 
* @param keystorePassword The password to the keystore 
* @param privateKeyAlias The alias of the private key in the keystore 
* @return The Issuer DN for the private key 
*/ 
private String getCertificateIssuerDN(String keystoreFilePath, String keystorePassword, String privateKeyAlias) { 
    try { 
     FileInputStream keyStoreFile = new FileInputStream(keystoreFilePath); 
     KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
     keyStore.load(keyStoreFile, keystorePassword.toCharArray()); 
     X509Certificate certificate = (X509Certificate)keyStore.getCertificate(privateKeyAlias); 
     return certificate.getIssuerDN().getName(); 
    } catch (IOException | NoSuchAlgorithmException | CertificateException | KeyStoreException e) { 
     //TODO: Add logging 
    } 
    return null; 
} 

}

ответ

1

Глядя на wikipedia article Я предполагаю, что это потому, что он реализует RFC 6979,

Это гарантирует, что к различен для каждого H (м) и непредсказуемым для злоумышленников, которые не знают секретный ключ х.

Это предотвращение нападений на секретный ключ.

+0

Вы правы. Спасибо за помощь. – David

Смежные вопросы