2012-06-07 13 views
7

Sto sviluppando la firma digitale distribuita che firma un documento e lo invia attraverso la rete al server delle applicazioni. Sto usando la programmazione dei socket in java per farlo. Penso che la chiave pubblica debba essere codificata o compressa, i valori xey sono in qualche modo rappresentati come dati binari singoli e salvati in un registro pubblico o in una rete.Ma non so come farlo in java.Come comprimere o codificare la chiave pubblica della curva ellittica e metterla in rete?

 // I have class like this 
      public class CryptoSystem{     

       EllipticCurve ec = new EllipticCurve(new P192()); 

       //------------------- 
       //-------------------- 

       public ECKeyPair generatekeyPair() 
       { 
        return ECKeyPair(ec); 

       } 


      }  
     // i don't think i have problem in the above 


    CryptoSystem crypto = new CryptoSystem(); 
    ECKeyPair keyPair = crypto.generateKeyPair(); 
    BigInteger prvKey = keyPair.getPrivateKey(); 
    ECPoint pubKey = keyPair.getPublicKey(); 
    // recommend me here to compress and send it the public key to a shared network. 

voglio sapere come codificare i parametri chiave e di dominio pubblico, in modo che il verificatore della firma sarà decodificare in modo da utilizzare it.because quando li si invia attraverso la rete al verificatore u gonna devono codifica come array di un singolo byte. Non uso il provider di Bouncy Castle. L'intera implementazione dell'algoritmo ECDSA è il mio progetto

+0

Come si fa a rappresentare in memoria? Sono solo grandi numeri interi, la serializzazione di loro dovrebbe essere facile. – CodesInChaos

+0

Do you vuoi usare la compressione dei punti? Questa è una tecnica in cui serializzi solo la coordinata x e il segno della coordinata y, quindi usa l'equazione della curva per ripristinare la coordinata y. – CodesInChaos

+0

sì, ma oltre alla compressione voglio mettere la compressione chiave pubblica nel registro di rete condiviso in modo che due o più server applicativi lo utilizzino per verificare la firma –

risposta

9

I punti di curva ellittica sono quasi sempre codificati utilizzando la codifica specificata in X9.62.

È facoltativo utilizzare la compressione del punto. È semplice codificare utilizzando la compressione dei punti, ma decodificare un punto compresso richiede un po 'più di lavoro, quindi a meno che non si abbia davvero bisogno di salvare i byte aggiuntivi, non mi preoccuperei. Fammi sapere se ne hai bisogno, e aggiungerò i dettagli. È possibile riconoscere i punti codificati X9.62 con compressione punti dal primo byte, che sarà 0x02 o 0x03.

La codifica senza compressione del punto è davvero semplice: inizia con un 0x04 (per indicare che non c'è compressione). Poi seguire con prima la coordinata x, quindi la coordinata y, sia con zeri a sinistra fino alla dimensione in byte del campo:

int qLength = (q.bitLength()+7)/8; 
byte[] xArr = toUnsignedByteArray(x); 
byte[] yArr = toUnsignedByteArray(y); 
byte[] res = new byte[1+2*qLength]; 
res[0] = 0x04; 
System.arraycopy(xArr, 0, res, qLength - xArr.length, xArr.length); 
System.arraycopy(yArr, 0, res, 2* qLength - yArr.length, nLength); 

decodifica questo è ovviamente banale.

+0

grazie, ho capito la risposta. dove devo salvare la chiave pubblica per essere utilizzata da uno o più server delle app nell'area remota? –

+0

e quali sono i parametri del dominio (q, a, b, G, n, h), come passano alle app di verifica delle firme remote, perché ci sono dinamicamente le curve ellittiche che si scelgono come un segno. p-192, p-224, ...., p-512 parametri del dominio della curva ellittica raccomandati –

+0

@Clickmit: presumo che avessi parametri di dominio statici e li ho solo codificati a ogni estremità. Se hai solo una piccola lista di curve supportate, vorrei fare qualcosa come anteporre un intero specificando quale curva stai usando. Se vuoi codificare tutti i parametri del dominio, ci sono anche degli standard (cerca la struttura ASN.1 di ECDomainParameters), ma penso che dovresti trovare un encoder DER AS.1 per quello. La codifica manuale di tale struttura non è banale. –

3

Sono abbastanza sicuro che l'implementazione BC utilizza la codifica X9.63, quindi queste sarebbero codifiche piuttosto standardizzate. Sarà necessario aggiungere il provider del Castello gonfiabile al vostro JRE (Security.addProvider(new BouncyCastleProvider()), consultare la documentazione rimbalzante.

public static void showECKeyEncodings() { 

    try { 
     KeyPairGenerator kp = KeyPairGenerator.getInstance("ECDSA"); 
     ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable 
       .getParameterSpec("prime192v1"); 
     kp.initialize(ecSpec); 
     KeyPair keyPair = kp.generateKeyPair(); 

     PrivateKey privKey = keyPair.getPrivate(); 
     byte[] encodedPrivKey = privKey.getEncoded(); 
     System.out.println(toHex(encodedPrivKey)); 

     PublicKey pubKey = keyPair.getPublic(); 
     byte[] encodedPubKey = pubKey.getEncoded(); 
     System.out.println(toHex(encodedPubKey)); 

     KeyFactory kf = KeyFactory.getInstance("ECDSA"); 
     PublicKey pubKey2 = kf.generatePublic(new X509EncodedKeySpec(encodedPubKey)); 
     if (Arrays.equals(pubKey2.getEncoded(), encodedPubKey)) { 
      System.out.println("That worked for the public key"); 
     } 

     PrivateKey privKey2 = kf.generatePrivate(new PKCS8EncodedKeySpec(encodedPrivKey)); 
     if (Arrays.equals(privKey2.getEncoded(), encodedPrivKey)) { 
      System.out.println("That worked for the private key"); 
     } 

    } catch (GeneralSecurityException e) { 
     throw new IllegalStateException(e); 
    } 

} 
+0

Non sto riutilizzando l'implementazione di Bouncy Castle di ECDSA.sto implementando da solo ma ho difficoltà a codificare i parametri del Dominio per inviarli via rete come array di un singolo byte e dovrebbero essere decodificati dal lato del verificatore –

+1

In tal caso, ti imploro di guardare proprio permissiva alla base dell'implementazione di Bouncy Castle, se non per copiare poi solo per guardare la codifica X9.62 standard dei parametri del dominio. BSI TR-03111 ha anche un metodo (più semplice) di codifica dei parametri di dominio. –

+1

Anche questo esempio sembra funzionare in JDK 1.8 tranne per il fatto che è necessario passare "EC" a KeyPairGenerator e KeyFactory. – kravietz