2017-01-30 5 views
0

私は同じ会社によって書かれたプラグインを実行する必要があるが、実行時に発見されたアプリケーションを持っている。プラグインjarが同じ会社によって作成されたことを認証する方法は?

セキュリティのため、各プラグインが私たちによって書かれたことをアプリケーションが認証するようにします。 サードパーティのコードで認証を実行する必要はありません。

この認証を実行する簡単な方法は何ですか?

チャレンジレスポンスを取得するのが妥当ですか、プラグインジャーに署名する必要がありますか?

プラグインjarに署名する必要がある場合は、どのAPIを使用して認証しますか?

+0

プラグインのメカニズムを制御していますか? –

+0

Jarsを扱っているので、ビルドの依存関係/ jar管理にはMavenやGradleのようなものがあります。 – SomeStudent

+0

@ThorbjørnRavnAndersen - そうです。理想的には、Java SE標準ライブラリのほかに、0個または少数の依存関係を持つものが理想的です。 –

答えて

0

これは私が読んで実験した後の答えです。

第三者コードを認証する必要がないため、この場合はself-signed certificateで十分です。ホスティングコードは、公開鍵を使用してプラグインを検証できます。

詳細

以下の例では、デフォルトのキーアルゴリズム。より安全なアルゴリズムを-keyalgで指定したい場合があります。

ストア、公開鍵/秘密鍵のペア、および含む自己署名証明書を作成し、公開鍵

keytool -genkeypair -alias myalias -validity 365 -keystore mykeystore 

妥当性は、日中に測定されます。

輸出ビルド時には、公開鍵

keytool -export -keystore mykeystore -alias myalias -file mycertificate.cer 

を含む証明書は、実行時にプラグインのjar

jarsigner -keystore mykeystore -signedjar my_signed.jar my_unsigned.jar myalias 

に署名プラグインのjarファイルを認証します内容

このt estハーネスを使用して、後続のコードをテストすることができます。あなたは瓶に適切なエントリを確認することができ、jarファイルと公開鍵が与えられ

private static PublicKey 
    getPublicKeyFromCertificate(File certificateFile) 
    throws CertificateException, FileNotFoundException 
    { 
     CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); 

     FileInputStream inCertificate = new FileInputStream(certificateFile); 
     Certificate certificate = certificateFactory.generateCertificate(inCertificate); 
     return certificate.getPublicKey(); 
    } 

public class CEVerify { 
    public static void main(String[] args) throws IOException, CertificateException { 
    File jarFile = new File("C:\\myplugins\\my_signed.jar"); 
    String certificatePath = "C:\\mycertificates\\mycertificate.cer"; 

    File certificateFile = new File(certificatePath); 

    PublicKey publicKey = getPublicKeyFromCertificate(certificateFile); 

    JarFile jar = new JarFile(jarFile); 
    boolean isVerified = verify(jar, publicKey); 
    if (isVerified) { 
     System.out.println("Verified!"); 
    } 
    else { 
     System.err.println("NOT verified!"); 
    } 

    } 

あなたは、このような証明書から公開鍵を抽出することができます。 RSAのように別の-keyalgを使用した場合は、他のファイルを除外する必要があります。

private static boolean 
    verify(JarFile jar, PublicKey publicKey) throws IOException { 
     Enumeration<JarEntry> jarEntries = jar.entries(); 
     while (jarEntries.hasMoreElements()) { 
     JarEntry jarEntry = jarEntries.nextElement(); 

     if (jarEntry.isDirectory()) { 
      continue; 
     } 
     else { 
      String entryName = jarEntry.getName(); 
      if (entryName.endsWith(".SF") || entryName.endsWith(".DSA")) { 
       continue; 
      } 
      else if (! verifyJarEntry(jar, publicKey, jarEntry)) { 
       return false; 
      } 
     } 
     } 

     return true; 
    } 

これは、jarファイル内の特定のファイルを認証します。 jarエントリ内のすべてのバイトを読み取ってから証明書を取得する必要があることに注意してください。

private static boolean 
    verifyJarEntry(JarFile jar, PublicKey publicKey, JarEntry jarEntry) 
    throws IOException 
    { 
     try { 
      InputStream in = jar.getInputStream(jarEntry); 
      readAllOf(in); 

      // public Certificate[] getCertificates() 
      // ... This method can only be called once the JarEntry has been 
      // completely verified by reading from the entry input stream 
      // until the end of the stream has been reached. Otherwise, this 
      // method will return null. 

      Certificate[] certificates = jarEntry.getCertificates(); 
      if ((null == certificates) || (0 == certificates.length)) { 
       return false; 
      } else { 
       for (int i = 0; i < certificates.length; ++i) { 
        Certificate certificate = certificates[i]; 
        try { 
         certificate.verify(publicKey); 
         return true; 
        } catch (Exception e) { 
         continue; 
        } 
       } 
       return false; 
      } 
     } catch (SecurityException e) { 
      return false; 
     } 
    } 

最後に、これはjarエントリ内のすべてのバイトを読み取るために上で呼び出されたメソッドです。

private static void readAllOf(InputStream in) throws IOException { 
     byte[] buffer = new byte[4096]; 
     while (0 < in.read(buffer)) { 
      continue; 
     } 
    } 
関連する問題