2013-08-24 35 views
0

我正在構建與在線Web服務進行通信的Android應用程序。我計劃在GitHub上發佈應用程序的源代碼。對於我的生產版本,它將利用我的個人網絡服務,我想只允許我的數字簽名apk連接。確認與密鑰庫的APK身份

是否可以請求APK的密鑰庫並確認該密鑰庫的用戶名/密碼?

如果這是不可能的,我該怎麼產生這個功能?

編輯:

我已經讀入類Certificate它看起來像我也許能對用戶的公鑰/私鑰,以確認身份。但我仍然不確定的實現

+0

密鑰庫中的用戶名/密碼?如果我正確理解你,你想限制你的web服務到你簽名的apks? – dst

+0

這是正確的,現在唯一可以想象的方法是確認apk是由我用我的用戶名/密碼進行數字簽名的。 – KDEx

+0

你用一個用戶名簽名?怎麼樣? – dst

回答

1

我用這個的 -

static public String getPackageFingerPrint(Context ctx) { 
     PackageManager pm = ctx.getPackageManager(); 
     String packageName = ctx.getPackageName(); 
     int flags = PackageManager.GET_SIGNATURES; 

     PackageInfo packageInfo = null; 

     try { 
       packageInfo = pm.getPackageInfo(packageName, flags); 
     } catch (NameNotFoundException e) { 
       return ""; 
     } 
     Signature[] signatures = packageInfo.signatures; 

     byte[] cert = signatures[0].toByteArray(); 

     InputStream input = new ByteArrayInputStream(cert); 

     CertificateFactory cf = null; 
     try { 
       cf = CertificateFactory.getInstance("X509"); 


     } catch (CertificateException e) { 
       return ""; 
     } 
     X509Certificate c = null; 
     try { 
       c = (X509Certificate) cf.generateCertificate(input); 
     } catch (CertificateException e) { 
       return ""; 
     } 


     try { 
      MessageDigest md = MessageDigest.getInstance("SHA1"); 
      byte[] publicKey = md.digest(c.getPublicKey().getEncoded()); 


      StringBuffer hexString = new StringBuffer(); 
      for (int i=0;i<publicKey.length;i++) { 
       String appendString = Integer.toHexString(0xFF & publicKey[i]); 
       if(appendString.length()==1)hexString.append("0"); 
       hexString.append(appendString); 
       } 


      return hexString.toString(); 

     } catch (NoSuchAlgorithmException e1) { 
      return ""; 
     } 
    } 

我用你的方法看到的問題是,任何人都可以決定包指紋或你的包,並將其發送到您的Web服務。更好的可能性是使用質詢 - 響應機制:您的Web服務向您發送一個唯一的會話令牌,您的應用使用共享算法加密或摘要,然後將此加密的令牌發送回您的服務進行驗證。當然,你不想將這個算法發佈到github上。

+0

此方法看起來非常有用。然而,對於你提供的關於共享算法的提議 - 我不願意在apk中放置任何「祕密」,因爲它是如此微不足道的反編譯,並找出幾乎任何部分的應用程序編碼 – KDEx

+0

當然這是真的 - - 你可以混淆你的代碼,但最終,沒有安全的java這樣的東西。但即使你使用鑰匙或指紋,一旦它通過電線,這是公平的遊戲。 – 323go

0

您無法將Web服務限制爲由特定密鑰簽名的apks。

您的apk的簽名得到了Android操作系統的驗證,並且不直接與設備連接的Web服務共享。即使您從密鑰庫中讀取簽名並將其與請求一起發送,攻擊者也可能只是發送相同的簽名(例如相同的字節流)而無需訪問您的私鑰。他只需要抓住已簽名的apk,從密鑰庫中讀取字節(或者聽取合法請求)並破壞數據。

您需要簽署具有一定安全級別的個別請求。但是,如果你保留一個私鑰在發佈版本(密鑰沒有分佈在gitHub上),並使用該密鑰簽名請求,那麼你不安全,因爲私鑰是作爲apk的一部分分發的,因此可以輕鬆提取。

以任何方式您的API可以被其他apks訪問。

但是,可能有另一種方法來限制您的API,例如通過使用許可令牌等。在這種情況下,您可能不在乎用戶是否自己構建apk,只要他擁有有效的許可證令牌。如果許可證令牌被利用和分發,您可能會對該許可證令牌中的大量流量做出反應,例如阻止它接受進一步的請求。由於我不使用Google Play,因此我不確定他們可以從服務器獲得多少驗證,但application licensing portal是搜索合適令牌的好起點。