2010-05-24 38 views
5

Tôi muốn phát triển Trình tạo khóa cho các ứng dụng điện thoại của mình. Hiện tại tôi đang sử dụng một dịch vụ bên ngoài để thực hiện công việc nhưng tôi hơi lo ngại rằng dịch vụ có thể bị gián tuyến một ngày vì thế tôi sẽ có một chút dưa chua.Xây dựng Trình tạo mã khóa 'Kích hoạt' trong JAVA

Cách xác thực hoạt động ngay bây giờ.

  1. Khóa công khai được lưu trữ trên điện thoại.
  2. Khi người dùng yêu cầu khóa 'ID điện thoại' được gửi đến "Dịch vụ tạo khóa" và khóa phím được mã hóa được trả về và lưu trữ bên trong tệp giấy phép.
  3. Trên điện thoại, tôi có thể kiểm tra xem phím có dành cho điện thoại hiện tại hay không bằng cách sử dụng phương thức getPhoneId() mà tôi có thể kiểm tra bằng điện thoại hiện tại và cấp hoặc không cấp quyền truy cập vào các tính năng.

Tôi thích điều này và nó hoạt động tốt, tuy nhiên, tôi muốn tạo "Dịch vụ tạo khóa" của riêng mình từ trang web của riêng mình.

Yêu cầu:

  1. Public và Private chính
  2. Encryption: (Bouncy Castle)
  3. Được viết bằng JAVA
  4. Phải hỗ trợ getApplicationId() (vì vậy mà nhiều ứng dụng có thể sử dụng cùng một bộ tạo khóa) và getPhoneId() (để lấy id điện thoại ra khỏi tệp giấy phép được mã hóa)
  5. Tôi muốn có thể gửi ApplicationId và Điện thoại Id cho dịch vụ tạo khóa cấp phép.

Ai đó có thể cho tôi một số gợi ý về cách thực hiện điều này không? Tôi đã dabbled xung quanh với một số mã hóa java nhưng chắc chắn không có chuyên gia và không thể tìm thấy bất cứ điều gì sẽ giúp tôi.

Danh sách các lớp Java tôi cần để khởi tạo sẽ hữu ích.

+0

@jax - bạn có thành công trong việc nghiên cứu câu hỏi này không? Tôi cũng đang tìm kiếm một bộ tạo khóa kích hoạt an toàn. – Stevko

+0

vâng, tôi đang đánh bóng nó ngay bây giờ - Tôi có thể cho bạn biết đó là một nỗi đau lớn trong # $% $ để thực hiện. – jax

+1

Thông tin về chủ đề này khan hiếm và khi bạn hỏi một câu hỏi mọi người nói với bạn rằng nếu bạn không hiểu bạn không nên làm điều đó - điều tôi nghĩ là vô lý - làm sao mọi người học được! Khi tôi hoàn thành API của mình, tôi có thể bán nó từ doridprofessor.com. Tuy nhiên, nếu muốn làm cho bạn sở hữu, hãy xem tại andappstore.com, họ có trên dịch vụ trực tuyến thực hiện điều này cho bạn. Bạn có thể tìm mã của họ và đảo ngược kỹ sư một chút. Lớp Base64 commons cũng rất hữu ích cho việc mã hóa các giấy phép nhị phân của bạn thành dạng văn bản có thể đọc được. – jax

Trả lời

1

Câu hỏi thú vị khiến tôi thử nghiệm một chút với nó. Nhưng như bạn có thể đã đoán, tôi đã không làm điều này trước đây. Nhưng có lẽ ai đó khác có thể xác nhận suy nghĩ của tôi - hoặc bác bỏ chúng nhưng xin vui lòng không có sự giảm giá;)

Tôi muốn sử dụng một số asymmetric algorithm chẳng hạn như RSA để ký một chuỗi dữ liệu phải khớp. . Chữ ký này được lưu trữ cùng với khóa công khai để xác minh nó mà không cần truy cập vào máy chủ.

Thể hiện như mã Java, điều này sẽ giống như thế này (dựa trên Signature Sign and Verify):

import java.security.*; 

public class Main { 
    public static void main(String args[]) throws Exception { 
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); 

    // our server, imagine it's a webservice 
    KeyServer server = new KeyServer(42); 

    // init client with a copy of public key from server 
    KeyClient client = new KeyClient(server.getPublicKey()); 

    // create string that identifies phone and application 
    byte[] data = (getPhoneId() + ":" + getApplicationId()).getBytes("utf-8"); 

    // send data to server for signature creation 
    byte[] digitalSignature = server.signData(data); 

    // verify on client side 
    System.out.println("verified = " + client.verifySig(data, digitalSignature)); 

    // bad data 
    byte[] wrongData = ("anotherPhoneId" + ":" + getApplicationId()).getBytes("utf-8"); 
    System.out.println("verified = " + client.verifySig(wrongData, digitalSignature)); 

    // bad signature 
    digitalSignature[5] = (byte) 0xff; 
    System.out.println("verified = " + client.verifySig(data, digitalSignature)); 
    } 

    private static String getPhoneId() { 
    return "somephone"; 
    } 

    private static String getApplicationId() { 
    return "someapp"; 
    } 

    public static class KeyClient { 

    private PublicKey _publicKey; 
    private Signature _signer; 

    public KeyClient(PublicKey publicKey) { 
     if (publicKey == null) { 
     throw new NullPointerException("publicKey"); 
     } 
     _publicKey = publicKey; 

     try { 
     _signer = Signature.getInstance("SHA1withRSA"); 
     } catch (NoSuchAlgorithmException e) { 
     throw new RuntimeException("failed to get Signature", e); 
     } 
    } 

    public boolean verifySig(byte[] data, byte[] sig) throws Exception { 
     synchronized (_signer) { 
     _signer.initVerify(_publicKey); 
     _signer.update(data); 
     return (_signer.verify(sig)); 
     } 
    } 
    } 

    public static class KeyServer { 

    private KeyPair _keyPair; 
    private Signature _signer; 

    public KeyServer(int seed) { 
     try { 
     _keyPair = generateKeyPair(seed); 
     } catch (Exception e) { 
     throw new RuntimeException("failed to generate key pair for seed " + seed, e); 
     } 

     try { 
     _signer = Signature.getInstance("SHA1withRSA"); 
     } catch (NoSuchAlgorithmException e) { 
     throw new RuntimeException("failed to get Signature", e); 
     } 
    } 

    public PublicKey getPublicKey() { 
     return _keyPair.getPublic(); 
    } 

    public byte[] signData(byte[] data) throws InvalidKeyException, SignatureException { 
     synchronized (_signer) { 
     _signer.initSign(_keyPair.getPrivate()); 
     _signer.update(data); 
     return (_signer.sign()); 
     } 
    } 

    private KeyPair generateKeyPair(long seed) throws Exception { 
     KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance("RSA"); 
     SecureRandom rng = SecureRandom.getInstance("SHA1PRNG", "SUN"); 
     rng.setSeed(seed); 
     keyGenerator.initialize(2048, rng); 
     return (keyGenerator.generateKeyPair()); 
    } 

    } 
} 
1

Vấn đề là, rằng mặc dù có những thuật toán mà là đủ mạnh, vấn đề là làm thế nào để bạn sử dụng chúng, bởi vì nếu bạn kết hợp các thuật toán đó sai thời trang hoặc sử dụng hạt giống xấu cho một số thuật toán, các phím yếu (ví dụ: chiều dài của chúng) bạn sẽ kết thúc với một thứ không an toàn. Vì vậy, kinh nghiệm nói, nó là tốt hơn, để không thử thực hiện nó cho mình và rủi ro lỗi cho đến khi bạn đủ tự tin với lý thuyết mật mã.

Tuy nhiên, câu trả lời khác dường như là một ví dụ điển hình.

Các vấn đề liên quan