2014-10-02 2 views
5

मैं secp256r1 (एनआईएसटी पी -256, पी -256, प्राइम 256 वी 1) सार्वजनिक कुंजी की सहायता से SHA256withECDSA हस्ताक्षर मान्य करने की आवश्यकता वाले एक ऐसे अनुप्रयोग को विकसित कर रहा हूं।मैं ईसी सार्वजनिक कुंजी बाइट्स से PublicKey ऑब्जेक्ट कैसे प्राप्त कर सकता हूं?

सार्वजनिक कुंजी कुछ समय पहले किसी भिन्न अनुप्रयोग द्वारा उत्पन्न होती है और हेक्स एन्कोडिंग में मेरे डेटाबेस में संग्रहीत होती है। हेक्स स्ट्रिंग का प्रारूप हेक्स स्ट्रिंग के बराबर है ओपनएसएसएल openssl ec -in x.pem -noout -text को x.pem पर कॉल करते समय उत्पन्न होगा जो पहले openssl ecparam -genkey -name secp256r1 -out x.pem द्वारा उत्पन्न किया गया था। संदेश और हस्ताक्षर एक अलग आवेदन से प्राप्त होते हैं। निम्नलिखित परीक्षण डेटा पर विचार करें:

// Stored in Database 
byte[] pubKey = DatatypeConverter.parseHexBinary("049a55ad1e210cd113457ccd3465b930c9e7ade5e760ef64b63142dad43a308ed08e2d85632e8ff0322d3c7fda14409eafdc4c5b8ee0882fe885c92e3789c36a7a"); 

// Received from Other Application 
byte[] message = DatatypeConverter.parseHexBinary("54686973206973206a75737420736f6d6520706f696e746c6573732064756d6d7920737472696e672e205468616e6b7320616e7977617920666f722074616b696e67207468652074696d6520746f206465636f6465206974203b2d29"); 
byte[] signature = DatatypeConverter.parseHexBinary("304402205fef461a4714a18a5ca6dce6d5ab8604f09f3899313a28ab430eb9860f8be9d602203c8d36446be85383af3f2e8630f40c4172543322b5e8973e03fff2309755e654"); 

अब इस वैध हस्ताक्षर होना चाहिए।

मेरा उद्देश्य जावा और/या बाउंसीकैसल क्रिप्टो एपीआई का उपयोग कर संदेश पर हस्ताक्षर को मान्य करना है। मुझे लगता है कि के लिए एक विधि isValidSignature बनाया है:

KeyFactory.generatePublic:

private static boolean isValidSignature(byte[] pubKey, byte[] message, 
     byte[] signature) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException, InvalidKeySpecException { 
    Signature ecdsaVerify = Signature.getInstance("SHA256withECDSA", new BouncyCastleProvider()); 
    ecdsaVerify.initVerify(getPublicKeyFromHex(pubKey)); 
    ecdsaVerify.update(message); 
    return ecdsaVerify.verify(signature); 
} 

मैं सार्वजनिक कुंजी को निकालने की कोशिश की है

private static PublicKey getPublicKeyFromHex(byte[] pubKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException { 
    KeyFactory fact = KeyFactory.getInstance("ECDSA", new BouncyCastleProvider()); 
    return fact.generatePublic(new X509EncodedKeySpec(pubKey)); 
} 

लेकिन यह एक java.security.spec.InvalidKeySpecException (डीईआर लंबाई फेंकता 4 बाइट से अधिक: 26)। मैं इसे पार्स करने के लिए क्या कर सकता हूं?

+0

कोड कॉपी करते समय सहीता की अनुमति देने के लिए; OpenSSL के लिए '-noout' विकल्प गलत वर्तनी है। – CarlosRos

+0

धन्यवाद, सही। –

उत्तर

11

Bouncy Castle example code on elliptic curve key pair Generation and key factories मुझे बहुत करीब मिला।

एक बार मैं एक ECDSA कुंजी कारखाने और secp256r1/NIST P-256/P-256/prime256v1 वक्र मैं ECPointUtil.decodePoint उपयोग करने के लिए एक वक्र बिंदु प्राप्त करने में सफल के लिए एक वक्र विनिर्देश बनाने में कामयाब रहे। इसके बाद मैं एक सार्वजनिक कुंजी विनिर्देश उत्पन्न कर सकता था जिसने मुझे इस तरह की सार्वजनिक कुंजी उत्पन्न करने में सक्षम बनाया:

private PublicKey getPublicKeyFromBytes(byte[] pubKey) throws NoSuchAlgorithmException, InvalidKeySpecException { 
    ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("prime256v1"); 
    KeyFactory kf = KeyFactory.getInstance("ECDSA", new BouncyCastleProvider()); 
    ECNamedCurveSpec params = new ECNamedCurveSpec("prime256v1", spec.getCurve(), spec.getG(), spec.getN()); 
    ECPoint point = ECPointUtil.decodePoint(params.getCurve(), pubKey); 
    ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(point, params); 
    ECPublicKey pk = (ECPublicKey) kf.generatePublic(pubKeySpec); 
    return pk; 
} 
+0

धन्यवाद, मैं केवल पोर्टेबल उछाल वाले महल का उपयोग करके ऐसा करने की कोशिश कर रहा हूं, कोई विचार? मैं विफल रहा क्योंकि एंड्रॉइड.मोमो में कोई ईसीपीओइंट नहीं है – Ivan

संबंधित मुद्दे