2011-03-08 20 views
11

Tamam, bu, "Nereden başlayacağına dair hiçbir fikrim yok" sorularının bir diğeridir, bu yüzden umarım cevabı basittir. Ancak, neyi arayacağımı gerçekten bilmiyorum ve şimdiye kadar yaptığım girişimler çok fazla kullanılmadı.OpenSAML ile kullanmak için özel anahtar nasıl okunur?

Özel (şu anda disk) bir dosyadan özel bir anahtar okumak istiyorum. Nihayetinde anahtar bir veritabanında yer alacaktır, ancak bu an için yeterince iyi olacaktır ve bu farkın anahtar malzemenin ayrıştırılması üzerinde gerçek bir dayanağı olmamalıdır. Anahtarın genel bölümünü tutan (hata ayıklayıcı tarafından onaylanmış) bir Credential örneği oluşturabildim, ancak özel bölümü nasıl okuyacağımı anlayamıyorum. . Gibi anahtar çifti oluşturulan:

openssl genrsa 512 > d:\host.key 
openssl req -new -x509 -nodes -sha1 -days 365 -key d:\host.key > d:\host.cert 

(Evet, 512 bitlik RSA anahtarları uzun zaman önce kırılmış olduğunu biliyoruz API işe almaya çalışırken için, Ancak, ben sistemi tüketmek için hiçbir neden görmüyorum gereksiz entropi kaynağı)

kod şimdiye kadar geçerli:.

import org.opensaml.xml.security.credential.Credential; 
import org.opensaml.xml.security.x509.BasicX509Credential; 

private Credential getSigningCredential() 
throws java.security.cert.CertificateException, IOException { 
    BasicX509Credential credential = new BasicX509Credential(); 

    credential.setUsageType(UsageType.SIGNING); 

    // read public key 
    InputStream inStream = new FileInputStream("d:\\host.cert"); 
    CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
    X509Certificate cert = (X509Certificate)cf.generateCertificate(inStream); 
    inStream.close(); 
    credential.setEntityCertificate(cert); 

    // TODO: read private key 

    // done. 
    return credential; 
} 

Ama nasıl credential özel anahtar kısmına dosyayı host.key okuyoruz, bu yüzden kullanabilirsinizoluşturulanörneği veri imzalamak için?

cevap

19

BasicX509Credential, standart Java'nın bir parçası değildir; OpenSAML'den org.opensaml.xml.security.x509.BasicX509Credential hakkında konuşuyorsunuzdur.

credential.setPrivateKey() ile ayarlayacağınız bir PrivateKey istersiniz. Bir PrivateKey almak için öncelikle Java yani PKCS #, 8 okuyabileceği bir biçime özel anahtarı dönüştürmek gerekir:

openssl pkcs8 -topk8 -nocrypt -outform DER <D:\host.key> D:\host.pk8 

Ardından, Java dan:

RandomAccessFile raf = new RandomAccessFile("d:\\host.pk8", "r"); 
byte[] buf = new byte[(int)raf.length()]; 
raf.readFully(buf); 
raf.close(); 
PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(buf); 
KeyFactory kf = KeyFactory.getInstance("RSA"); 
PrivateKey privKey = kf.generatePrivate(kspec); 

ve voilà! senin PrivateKey var. Varsayılan olarak

, openssl kendi formatında anahtarı yazıyor o PEM onları kodlar, ve, (RSA anahtarları, PKCS # 8 bu biçimdeki etrafında sarıcı olur) bir başlık ve bir altlık içeren hangi Base64. Her iki özellik de sade Java tarafından desteklenmez, dolayısıyla PKCS # 8'e dönüştürülür. -nocrypt seçeneği, PKCS # 8'in özel anahtarın isteğe bağlı parola tabanlı şifrelemesini desteklemesidir.

Uyarı: gerçekten gerçekten daha uzun RSA anahtarını kullanmak istiyorum. 512 bit zayıftır; 1999 yılında birkaç yüz bilgisayarla 512 bit RSA anahtarı kırıldı. 2011 yılında, 12 yıllık teknolojik gelişmelerle, 512-bit RSA anahtarının neredeyse herkes tarafından kırılabileceğini varsayalım. Bu nedenle, 1024 bit RSA anahtarlarını en az kullanın (tercihen, 2048 bit; anahtarın kullanıldığı zaman hesaplamalı genel gider o kadar da kötü değil, yine de saniyede yüzlerce imza gerçekleştirebilirsiniz).

+0

Evet, BasicX509Credential OpenSAML dan, yani gözetimi üzgünüm. Bunu kesinlikle deneyeceğim. Ve evet, 512 bit RSA anahtarlarının herhangi bir şekilde güvenli olmadığını bildiğimi, ancak bu özel kurulumun * herşeyin işe yaramaya çalıştığı için kesinlikle * olduğunu biliyorum, bu yüzden anahtar uzunluğu bir sorun değil. –

+0

Bir çekicilik gibi çalışır gibi görünüyor, çok teşekkür ederim! Tabii ki, imzalama kodum bozuk görünüyor, ancak en azından hata ayıklayıcısına göre, diskteki iki dosyadan uygun bir 'Kimlik Bilgisi 'alıyorum. Tur ile birlikte ... –

+0

Teşekkür ederim. Windows'da < and > yönlendirerek gizemli sorunları yaşadım, bu yüzden onları -in ve -out anahtarlarıyla değiştirmek isteyebilirsiniz. –

1

Bu soru, SAML ile ilgilidir ve XMLObject öğesinin imzalanması için özel anahtar almak isteyen kişilerle de ilgilidir.yanıt yukarıda iyi çalışıyor ve aynı zamanda mümkün olduğunca iyi bir anahtar deposundan özel anahtarı almak için: Bu istenen özgün sorgu daha fazla kodudur

 Properties sigProperties = new Properties(); 

    sigProperties.put("org.apache.ws.security.crypto.provider","org.apache.ws.security.components.crypto.Merlin"); 
    sigProperties.put("org.apache.ws.security.crypto.merlin.keystore.type","jks"); 
    sigProperties.put("org.apache.ws.security.crypto.merlin.keystore.password","keypass"); 
    sigProperties.put("org.apache.ws.security.crypto.merlin.keystore.alias","keyalias"); 
    sigProperties.put("org.apache.ws.security.crypto.merlin.keystore.file","keystore.jks"); 

    Crypto issuerCrypto = CryptoFactory.getInstance(sigProperties); 

    String issuerKeyName = (String) sigProperties.get("org.apache.ws.security.crypto.merlin.keystore.alias"); 

    //See http://ws.apache.org/wss4j/xref/org/apache/ws/security/saml/ext/AssertionWrapper.html 'signAssertion' method 
    // prepare to sign the SAML token 
    CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS); 
    cryptoType.setAlias(issuerKeyName); 
    X509Certificate[] issuerCerts = issuerCrypto.getX509Certificates(cryptoType); 
    if (issuerCerts == null) { 
     throw new WSSecurityException(
       "No issuer certs were found to sign the SAML Assertion using issuer name: " 
         + issuerKeyName); 
    } 

    String password = ADSUnitTestUtils.getPrivateKeyPasswordFromAlias(issuerKeyName); 

    PrivateKey privateKey = null; 
    try { 
     privateKey = issuerCrypto.getPrivateKey(issuerKeyName, password); 
    } catch (Exception ex) { 
     throw new WSSecurityException(ex.getMessage(), ex); 
    } 


    BasicX509Credential signingCredential = new BasicX509Credential(); 
    signingCredential.setEntityCertificate(issuerCerts[0]); 
    signingCredential.setPrivateKey(privateKey); 

    signature.setSigningCredential(signingCredential); 

ama onlar BasicX509Credential ulaşmak için çalışıyoruz görünüyor.

sayesinde Yogesh

İlgili konular