구르는돌

블로그 이미지
by soil21
  • Total hit
  • Today hit
  • Yesterday hit

'밥벌이'에 해당되는 글 30건

  1. 2011.02.15
    [android/ssl] Trusting SSL certificates 5
  2. 2011.02.15
    [android/java]https 접근
  3. 2011.02.08
    How to implement Push Notifications for Android
  4. 2010.09.09
    Ubuntu 9.10 에서 YAFFS2 Mount 하기
  5. 2010.02.19
    Android(2.1) 개발 환경 설정
  6. 2010.02.13
    모토로이
  7. 2010.02.13
    [펌]드로이드/안드로이드폰 사용 팁 (Tips and Tricks)
  8. 2009.05.16
    우분투 설치 및 shoppingos 설치
  9. 2009.04.22
    ubuntu mplayer 설치 및 mms 캡춰
  10. 2009.02.17
    USB stick으로 윈도우즈 설치 하기
http://blog.antoine.li/index.php/2010/10/android-trusting-ssl-certificates/

Friday, October 22nd, 2010 | Author: Antoine Hauck

Two weeks ago I got the task to establish TLS secured connections via certificates to a service endpoint.
I thought it’s not a big deal, because the endpoint already uses an EV certificate from a trusted CA (SwissSign) in Switzerland. Therefore I shouldn’t have to worry that the certificate would be considered as untrusted so I don’t have to import it to the trusted certs in the  Java  key store etc.
FAIL! I’ve got a security exception, cert is not trusted. Same problem when I visit the website with the browser. Ok, that’s bad, SwissSign is not such a big player like thawte, so, it needs some time till it will be added to the android trusted CA list. But, when I visit thawte.com, their cert is also not trusted by android. WTF?
Windows Phone and iPhone trust my SwissSign CA and don’t complain.

So, let’s ask google, stackoverflow and the blogosphere. Found a lot of solutions how to disable certificate checking entirely.
Yeah, great, this will solve my problem, my connection will be “secure” and everyone will be able to intercept my connection and inject his own certificate. But I finally found the solution with help from other sites and some testing and debugging.

The Solution

The following main steps are required to achieve a secured connection from trusted Certification Authorities.

  1. Grab all required certificates (root and any intermediate CA’s)
  2. Create a keystore with keytool and the BouncyCastle provider and import the certs
  3. Load the keystore in your android app and use it for the secured connections
    • Don’t use the standard java.net.ssl.HttpsURLConnection for the secure connection. Use the Apache HttpClient (Version 4 atm) library, which is already built-in in android. It’s built on top of the java connection libraries and is, in my opinion, faster, better modularized and easier to understand.

Step 1: Grab the certs

You have to obtain all certificates that build a chain from the endpoint certificate the whole way up to the Root CA. This means, any (if present) Intermediate CA certs and also the Root CA cert. You don’t need to obtain the endpoint certificate.
You can obtain those certs from the chain (if provided) included in the endpoint certificate or from the official site of the issuer (in my case SwissSign).

Ensure that you save the obtained certificates in the Base64 encoded X.509 format. The content should look similar to this:

1
2
3
-----BEGIN CERTIFICATE-----
MIIGqTC.....
-----END CERTIFICATE-----

Step 2: Create the keystore

Download the BouncyCastle Provider and store it to a known location.
Also ensure that you can invoke the keytool command (usually located under the bin folder of your JRE installation).

Now import the obtained certs (don’t import the endpoint cert) into a BouncyCastle formatted keystore.
I didn’t tested it, but I think the order of importing the certificates is important. This means, import the lowermost Intermediate CA certificate first and then all the way up to the Root CA certificate.

With the following command a new keystore (if not already present) with the password mysecret will be created and the Intermediate CA certificate will be imported. I also defined the BouncyCastle provider, where it can be found on my file system and the keystore format. Execute this command for each certificate in the chain.

1
keytool -importcert -v -trustcacerts -file "path_to_cert/interm_ca.cer" -alias IntermediateCA -keystore "res/raw/myKeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret

Verify if the certificates were imported correctly into the keystore:

1
keytool -list -keystore "res/raw/myKeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret

Should output the whole chain:

1
2
RootCA, 22.10.2010, trustedCertEntry, Thumbprint (MD5): 24:77:D9:A8:91:D1:3B:FA:88:2D:C2:FF:F8:CD:33:93
IntermediateCA, 22.10.2010, trustedCertEntry, Thumbprint (MD5): 98:0F:C3:F8:39:F7:D8:05:07:02:0D:E3:14:5B:29:43

Now you can copy the keystore as a raw resource in your android app under res/raw/

Step 3: Use the keystore in your app

First of all we have to create a custom Apache HttpClient that uses our keystore for HTTPS connections:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class MyHttpClient extends DefaultHttpClient {
 
    final Context context;
 
    public MyHttpClient(Context context) {
        this.context = context;
    }
 
    @Override
    protected ClientConnectionManager createClientConnectionManager() {
        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        // Register for port 443 our SSLSocketFactory with our keystore
        // to the ConnectionManager
        registry.register(new Scheme("https", newSslSocketFactory(), 443));
        return new SingleClientConnManager(getParams(), registry);
    }
 
    private SSLSocketFactory newSslSocketFactory() {
        try {
            // Get an instance of the Bouncy Castle KeyStore format
            KeyStore trusted = KeyStore.getInstance("BKS");
            // Get the raw resource, which contains the keystore with
            // your trusted certificates (root and any intermediate certs)
            InputStream in = context.getResources().openRawResource(R.raw.mykeystore);
            try {
                // Initialize the keystore with the provided trusted certificates
                // Also provide the password of the keystore
                trusted.load(in, "mysecret".toCharArray());
            } finally {
                in.close();
            }
            // Pass the keystore to the SSLSocketFactory. The factory is responsible
            // for the verification of the server certificate.
            SSLSocketFactory sf = new SSLSocketFactory(trusted);
            // Hostname verification from certificate
            sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
            return sf;
        } catch (Exception e) {
            throw new AssertionError(e);
        }
    }
}

We have created our custom HttpClient, now we can just use it for secure connections. For example when we make a GET call to a REST resource.

1
2
3
4
5
6
// Instantiate the custom HttpClient
DefaultHttpClient client = new MyHttpClient(getApplicationContext());
HttpGet get = new HttpGet("https://www.mydomain.ch/rest/contacts/23");
// Execute the GET call and obtain the response
HttpResponse getResponse = client.execute(get);
HttpEntity responseEntity = getResponse.getEntity();

That’s it. Took me long to figure it out, hope this helps and saves you that time.

I really hope that the android platform will implement a better mechanism in future releases for defining which Certification Authorities should be trusted or not or just expand their own trusted CA list. If they don’t, I can’t believe they will get good acceptance from the business sector. Ok, you can control which certificates you want to trust in your app, but you still can’t add thawte as a trusted CA in the android keystore and your browser will always complain about an untrusted CA. The only way I know to eliminate this problem is to root your phone (very user friendly) and add your CA manually to the android keystore.

Feel free to comment.

Tags: 
Category: Codingandroid
You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, ortrackback from your own site.

29 Responses

  1. OMG.
    Why is android team doing many things so complicated?!

  2. 2
    Saran 

    Still getting:
    Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: IssuerName(CN=thawte Primary Root CA, OU=”(c) 2006 thawte, Inc. ? For authorized use only”, OU=Certification Services Division, O=”thawte, Inc.”, C=US) does not match SubjectName(CN=Thawte SSL CA, O=”Thawte, Inc.”, C=US) of signing certificate

    :(

    Could you try importing and using certificates from this site:
    https://eu.battle.net/login/en/login.xml?app=armory&locale=en_US&ref=http%3A%2F%2Feu.wowarmory.com%2Fvault%2Fcalendar-feed.xml
    to see if you can get it to work?

  3. Hi Saran

    Hmm… I could reproduce your mentioned exception. Everything looks good with the certificates. I intercepted the HTTPS with Wireshark and saw something very interesting.

    The certificates are sent in the following order from the battle.net server:
    > *.battle.net
    >> thawte Primary Root CA
    >>> Thawte SSL CA (this is the intermedaite cert)

    I really can’t believe that the Cert. Path validation is so bad implemented, that the order how the server sends the certificates is important.
    But I’ve had a customer, whose server was sending the endpoint server certificate twice. And I got similar exceptions in android (IE, Chrome and Firefox weren’t complaining, they also didn’t show the duplicate in the chain). We removed the duplicate from the chain and everything worked fine.
    It’s really possible that the Cert. Path validation really depends on the correct order, which in may opinion sucks.

    I also tried in your case to import the thawte Root cert first and then the Intermediate cert into the keystore, but still got the same exception.

    Maybe you can write to battle.net to change their order, or write your own CertPathValidator or just use the crappier HttpsUrlConnection from the standard java libraries. There you can turn off certificate validation off at all (but you loose a lot of security).

    Hope this helps you a bit.

    Greetz

  4. 4
    Saran 

    Thanks for verifying, Antoine.

    I tried reverse-importing the certs into the store, but even though I imported them in this order:
    > *.battle.net
    >> thawte Primary Root CA
    >>> Thawte SSL CA (this is the intermedaite cert)

    I got this list:
    Keystore type: BKS
    Keystore provider: BC

    Your keystore contains 3 entries

    thawte Primary Root CA, 26.10.2010., trustedCertEntry,
    Certificate fingerprint (MD5): 8C:CA:DC:0B:22:CE:F5:BE:72:AC:41:1A:11:A8:D8:12
    *.battle.net, 26.10.2010., trustedCertEntry,
    Certificate fingerprint (MD5): FC:1C:1D:FE:FF:4A:AE:EA:11:4B:54:8C:2B:F0:C1:51
    Thawte SSL CA, 26.10.2010., trustedCertEntry,
    Certificate fingerprint (MD5): EB:A3:71:66:38:5E:3E:F4:24:64:ED:97:52:E9:9F:1B

    When I used that keystore, I got a different error:

    10-26 20:43:23.743: WARN/System.err(5423): javax.net.ssl.SSLException: Not trusted server certificate
    10-26 20:43:23.743: WARN/System.err(5423): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:371)
    10-26 20:43:23.753: WARN/System.err(5423): at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:92)
    10-26 20:43:23.753: WARN/System.err(5423): at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:381)
    10-26 20:43:23.753: WARN/System.err(5423): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:164)
    10-26 20:43:23.753: WARN/System.err(5423): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
    10-26 20:43:23.753: WARN/System.err(5423): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
    10-26 20:43:23.753: WARN/System.err(5423): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:348)
    10-26 20:43:23.753: WARN/System.err(5423): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
    10-26 20:43:23.763: WARN/System.err(5423): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
    10-26 20:43:23.763: WARN/System.err(5423): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
    10-26 20:43:23.763: WARN/System.err(5423): at org.homedns.saran.android.wowcalendarsync.network.NetworkUtilities.authenticateWithPass(NetworkUtilities.java:344)
    10-26 20:43:23.763: WARN/System.err(5423): at org.homedns.saran.android.wowcalendarsync.network.NetworkUtilities$1.run(NetworkUtilities.java:164)
    10-26 20:43:23.763: WARN/System.err(5423): at org.homedns.saran.android.wowcalendarsync.network.NetworkUtilities$5.run(NetworkUtilities.java:276)
    10-26 20:43:23.763: WARN/System.err(5423): Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Could not validate certificate signature.
    10-26 20:43:23.763: WARN/System.err(5423): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:168)
    10-26 20:43:23.763: WARN/System.err(5423): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:366)
    10-26 20:43:23.773: WARN/System.err(5423): … 12 more
    10-26 20:43:23.773: WARN/System.err(5423): Caused by: java.security.cert.CertPathValidatorException: Could not validate certificate signature.
    10-26 20:43:23.793: WARN/System.err(5423): at org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(PKIXCertPathValidatorSpi.java:342)
    10-26 20:43:23.793: WARN/System.err(5423): at java.security.cert.CertPathValidator.validate(CertPathValidator.java:202)
    10-26 20:43:23.793: WARN/System.err(5423): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:164)
    10-26 20:43:23.793: WARN/System.err(5423): … 13 more
    10-26 20:43:23.793: WARN/System.err(5423): Caused by: java.security.SignatureException: Signature was not verified.
    10-26 20:43:23.803: WARN/System.err(5423): at org.apache.harmony.security.provider.cert.X509CertImpl.fastVerify(X509CertImpl.java:601)
    10-26 20:43:23.803: WARN/System.err(5423): at org.apache.harmony.security.provider.cert.X509CertImpl.verify(X509CertImpl.java:544)
    10-26 20:43:23.803: WARN/System.err(5423): at org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(PKIXCertPathValidatorSpi.java:337)
    10-26 20:43:23.803: WARN/System.err(5423): … 15 more

    Using BC version you suggested and used keytool from these Java plugins (on Win7 64bit):
    jdk1.6.0_20 64bit
    jdk1.6.0_22 64bit
    jdk1.6.0_20 32bit

    I used this to retrieve certs:
    openssl s_client -connect eu.battle.net:443 -showcerts

  5. Hi Saran

    You should NOT place the *.battle.net certificate in your keystore. Your keystore should only contain the trusted issuers (the Root CA and any intermediate CA’s) and not the endpoint certificate itself.

    The check if your endpoint certificate is valid is done with several other criterias, like the hostname verification (does the cert correspond to the presented site).

    Please let me know if this is working.

  6. 6
    Saran 

    Yes, I tried it also with only Intermediate and Root (with having tried each of them imported as 1st at one time). Same result :(

  7. 7
    Saran 

    I’ve asked a question on StackOverflow:
    http://stackoverflow.com/questions/4115101/apache-httpclient-on-android-producing-certpathvalidatorexception-issuername

    Hopefully, someone will think of a solution…

  8. Hi Seran

    I tried to answer your question on stackoverflow. Hope it helps ;)

  9. 9
    Andreas 

    Thanks so much for this most useful info!

  10. 10
    Nilz 

    Hi Antoine,

    Your blog aims to tackle the exact problem I’m faced with, however I cannot get your solution to work.

    I keep getting the following in LogCat:

    11-19 15:12:34.777: ERROR/OpenSSLSocketImpl(520): Unknown error 5 during connect
    11-19 15:12:34.777: WARN/System.err(520): java.io.IOException: SSL handshake failure: I/O error during system call, Unknown error: 0
    11-19 15:12:34.786: WARN/System.err(520): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.nativeconnect(Native Method)
    11-19 15:12:34.786: WARN/System.err(520): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:305)
    11-19 15:12:34.786: WARN/System.err(520): at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:92)
    11-19 15:12:34.786: WARN/System.err(520): at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:321)
    11-19 15:12:34.795: WARN/System.err(520): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:129)
    11-19 15:12:34.795: WARN/System.err(520): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
    11-19 15:12:34.795: WARN/System.err(520): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
    11-19 15:12:34.795: WARN/System.err(520): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:348)
    11-19 15:12:34.795: WARN/System.err(520): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
    11-19 15:12:34.795: WARN/System.err(520): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
    11-19 15:12:34.795: WARN/System.err(520): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
    11-19 15:12:34.795: WARN/System.err(520): at me.test.TempActivity.onCreate(TempActivity.java:30)
    11-19 15:12:34.805: WARN/System.err(520): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    11-19 15:12:34.805: WARN/System.err(520): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
    11-19 15:12:34.814: WARN/System.err(520): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
    11-19 15:12:34.814: WARN/System.err(520): at android.app.ActivityThread.access$2200(ActivityThread.java:119)
    11-19 15:12:34.814: WARN/System.err(520): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
    11-19 15:12:34.814: WARN/System.err(520): at android.os.Handler.dispatchMessage(Handler.java:99)
    11-19 15:12:34.814: WARN/System.err(520): at android.os.Looper.loop(Looper.java:123)
    11-19 15:12:34.814: WARN/System.err(520): at android.app.ActivityThread.main(ActivityThread.java:4363)
    11-19 15:12:34.814: WARN/System.err(520): at java.lang.reflect.Method.invokeNative(Native Method)
    11-19 15:12:34.814: WARN/System.err(520): at java.lang.reflect.Method.invoke(Method.java:521)
    11-19 15:12:34.814: WARN/System.err(520): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
    11-19 15:12:34.814: WARN/System.err(520): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
    11-19 15:12:34.826: WARN/System.err(520): at dalvik.system.NativeStart.main(Native Method)

    Have you seen this before? Do you know what it means. Unfortunately I cannot share the certificate with you, but I can tell you that is was a p12 certificate which I exported to a X509 in windows xp.

    I really need help on this issue, any guidance would be a great help.

    Cheers,
    Nilz.

  11. 11
    Vlad 

    I tried to implemented and getting error. Any ideas?
    Here is my cert list

    {2df05992-4d0f-48af-9d89-342c0af1d238}, Nov 19, 2010, PrivateKeyEntry,
    Certificate fingerprint (MD5): 90:99:AC:3E:0A:22:7C:81:26:EC:6F:F4:04:F5:BB:A5
    GeotrustCA, Nov 19, 2010, trustedCertEntry,
    Certificate fingerprint (MD5): 67:CB:9D:C0:13:24:8A:82:9B:B2:17:1E:D1:1B:EC:D4

    11-19 12:34:42.577: WARN/System.err(4233): java.net.SocketException: The operation timed out
    11-19 12:34:42.587: WARN/System.err(4233): at org.apache.harmony.luni.platform.OSNetworkSystem.connectStreamWithTimeoutSocketImpl(Native Method)
    11-19 12:34:42.587: WARN/System.err(4233): at org.apache.harmony.luni.platform.OSNetworkSystem.connect(OSNetworkSystem.java:115)
    11-19 12:34:42.597: WARN/System.err(4233): at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:244)
    11-19 12:34:42.597: WARN/System.err(4233): at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:533)
    11-19 12:34:42.607: WARN/System.err(4233): at java.net.Socket.connect(Socket.java:1055)
    11-19 12:34:42.607: WARN/System.err(4233): at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:119)
    11-19 12:34:42.607: WARN/System.err(4233): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:143)
    11-19 12:34:42.617: WARN/System.err(4233): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
    11-19 12:34:42.617: WARN/System.err(4233): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
    11-19 12:34:42.617: WARN/System.err(4233): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:348)
    11-19 12:34:42.617: WARN/System.err(4233): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
    11-19 12:34:42.617: WARN/System.err(4233): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
    11-19 12:34:42.617: WARN/System.err(4233): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)

  12. 12
    Nick 

    I am very please with your tutorial; it is very thorough, but I am having flaky success.

    I am trying to use it to access Google’s login url: https://www.google.com/accounts/ClientLogin.

    I built everything just the way you detailed. Then the first time I ran it I got the expected response, but every time after that I got “javax.net.ssl.SSLException: Not trusted server certificate”.

    I’ve managed to get the desired response about 3 times, but nothing I change seems to have an effect. I sure would appreciate your help. I don’t know why Android makes this so difficult.

  13. 13
    swapnil 

    Hi,

    I like to know how google manage security certificate on Android. Reason i am asking is i came across a webcast by google for android and in that they mention storing certificate on Android device and using it instead of passing it everytime and accordingly this reduces data connection overhead.

    I am trying to achieve something similar.. i dont want to pass and receive server/client secure certificate everytime.
    My application is kind of pushengine without google PUSH API.

    Awaiting your views.

  14. Hi there

    Sorry for the late response, I was away for a couple of days.

    @Nilz:
    Never seen this error before. Can you provide some code (of the SSL Factory)? Maybe this helps:http://stackoverflow.com/questions/2899079/custom-ssl-handling-stopped-working-on-android-2-2-froyo

    @Vlad:
    The error is indicating that your operation timed out. Does your app executes the request to the server? You could intercept the traffic between the emulator and server for example with Wireshark. Sometimes the reply from the server could also be helpful.

    @Nick:
    Thanks.
    I think the Google ClientLogin uses a different approach.
    http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html

    @swapnil:
    Do you have the link or name of the mentioned webcast?
    I think I didn’t understand your question. What do you mean with storing the certificate and not passing it every time? The certificates are just passed during the establishment of the secure connection. After the cert. exchange (when all certificates are considered as trusted and valid) session keys are generated to secure the actual data. The session keys are valid until the connection closes.

    Found an useful link: http://tokudu.com/2010/how-to-implement-push-notifications-for-android/

    Greetz
    Antoine

  15. 15
    Gergo 

    Hi Antoine

    a very nice tutorial. Thank for that.
    My question is regarding client authentication. As far as i saw, the Apache HttpClient cannot handle this situation. When using only Server Auth, it works perfect , but when setting the Server to authenticate the client it fails.Do you know something about it ?
    I am trying it now the “Java way” with SSL Socket , but it fails too with ” Not trusted Server certifiate :(
    PLZ drop me an email if you have knowledge about turials or articles dealing with that problem

    Thanks in advance
    Gergo

  16. 16
    Gergo 

    Hi Antoine
    i figured out the problem with the “Not Trusted server certificate”
    It was the TrustManager. For some reason i do not know, The Trustmanager could not authenticate the certificate of the server. I have implemented my own.
    Client authentication works now.
    but if you have any idea how to do it with the Apache HttpClient, please drop me some line
    Thanks
    Gergo

  17. 17
    Lys 

    Hi,
    I found your post while looking for a solution to a similar problem. What I need is to connect to the remote server and download the cert for my app to use. Basically steps 1 and 2 but within the app itself. Any thoughts on how to do that?
    Thanks

  18. 18
    Martin 

    Hi,
    very useful, but I’m getting stuck with a 404 reply in the response. Have you any ideas to the reason for this?
    Wireshark shows a encrypted data load, length 288, which could corespond to the expected return from the Webservice

    Thanks

  19. @Gergo
    Hmm… AFAIK the Apache HttpClient is not able to handle client authentication with cert.

    @Lys
    Didn’t look very deep into those links.
    How to create your own keystore:
    http://www.coderanch.com/t/133048/Security/do-programmatically-create-keystore-import
    How to obtain the certificate from the site:
    http://helpdesk.objects.com.au/java/how-do-i-programatically-extract-a-certificate-from-a-site-and-add-it-to-my-keystore

    @Martin
    Can you access your resource via browser (without 404)?
    Maybe your HTTP headers are wrong and the server returns a 404 (but another error code would be much more appropriate in this case). In my opinion 288 bytes is not very much. Maybe the 404 error itself.

    You can try two approaches to see what’s going on with the response:
    1. If you have the private key of the webservice (I doubt that) you can encrypt the traffic with Wireshark. See http://htluo.blogspot.com/2009/01/decrypt-https-traffic-with-wireshark.html
    2. This is the PITA alternative, but you DON’T need the private key from the webservice. You can download fiddler2 (www.fiddler2.com), add the proxy certificate from fiddler (or create a new one to match the hostname to your webservice) to the app keystore. Then add an argument in your Android Emulator to use the fiddler proxy to connect to the webservice. Seehttp://mrrask.wordpress.com/2009/10/01/setting-up-the-android-emulator-for-http-debugging-using-fiddler2/ Your app in the emulator will connect to fiddler and there you can see the decrypted payload.

  20. 20
    pyko 

    Hi Antonie,
    Firstly, thanks heaps for this post ? it’s really really helpful & well written too! :D

    Implemented your solution and bumping into similar problem to Nick ? where the authentication is quite flaky :( though i’m not authing with Google accounts…

    Without changing anything, sometimes logging in will work first attempt… other times it requires several attempts to work..

    Looking at my stacktrace, I would’ve thought I got the order wrong…but I double checked that and what doesn’t make sense is that it sometimes works….
    javax.net.ssl.SSLException: Not trusted server certificate
    at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:371)
    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:92)
    at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:381)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:164)
    ….etc….
    Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: IssuerName(CN=thawte Primary Root CA, OU=”(c) 2006 thawte, Inc. ? For authorized use only”, OU=Certification Services Division, O=”thawte, Inc.”, C=US) does not match SubjectName(CN=Thawte SSL CA, O=”Thawte, Inc.”, C=US) of signing certificate
    at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:168)
    at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:366)
    … 24 more
    Caused by: java.security.cert.CertPathValidatorException: IssuerName(CN=thawte Primary Root CA, OU=”(c) 2006 thawte, Inc. ? For authorized use only”, OU=Certification Services Division, O=”thawte, Inc.”, C=US) does not match SubjectName(CN=Thawte SSL CA, O=”Thawte, Inc.”, C=US) of signing certificate
    at org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(PKIXCertPathValidatorSpi.java:373)
    at java.security.cert.CertPathValidator.validate(CertPathValidator.java:202)
    at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:164)
    … 25 more

  21. 21
    Martin 

    Hi again,
    the Ws can be browsed both on real device/emulator and from pc without problems. Cert chain is exported from firefox (https://google.com/accounts Worked this way).

    http works fine. I’ll investigate the output from wireshark

    Thnx
    martin

  22. 22
    Martin 

    no difference between wireshark output from http and https

    very strange

  23. 23
    allen 

    Hey everyone,

    I think I was able to find a fix to the sporadic nature of this solution. For those who used Antoine’s solution, but get inconsistent behavior, try importing just the root cert into your keystore and not the intermediate cert. not sure if this only worked for our setup with our servers, but it worked for us. I noticed all the exceptions I got were because it was trying to compare the root cert against the intermediate. Hope that helps!

  24. 24
    Martin 

    Hi,
    I finally found a solution for the 404 problem.
    the Webservice I’m calling is a .Net wcf service on an Intranet server, and the config of the ws was the problem.

    After doing a binding modification (http://www.codemeit.com/wcf/wcf-wsdl-xsdimport-schemalocations-link-to-local-machine-name-not-domain-name-while-hosted-in-iis.html)
    a super simple config file solved the problem

    I tried many other config solutions, but this one worked for me. Hope this can help others

    /Martin

  25. @pyko
    I think that the order of the present certificates could still be the problem, especially when you are connecting to an endpoint, which is behind a web farm. One miss configured web server could send the certificates in the wrong order, another one not.
    Check with Wireshark etc. if the order is correct.

    If you are not able to change the certificate order of the webserver, you could change the order programmatically.

    More info about changing the order programmatically can be found on this stackoverflow topic:http://stackoverflow.com/questions/4115101/apache-httpclient-on-android-producing-certpathvalidatorexception-issuername/4199518#4199518

    @allen:
    AFAIK every involved certificate must be in the keystore. Never tried to remove the intermediate cert. But I could imagine, that if the order of the certificates is sent wrong from the webserver, for example the first entry is the Root CA and not the Intermediate, then the Bouncy Castle checks only against the one and only Root CA certificate in the keystore and completes the checking. But this is just an assumption. You can also look at the link that I posted to pyko.

  26. 26
    Teresa 

    Hi Antoine,

    Very pleased with this tutorial. In my app, I am trying to send a soap request using ksoap2, which is working fine in my test environment. If I am trying to connect to a secured site, getting ‘Not trusted server certificate’. I dont want to bypass the certificate check like it was mentioned in some of the blogs. Is it possible to implement your solution with soap. Here is how I am sending the request.

    HttpsTransportSE transport = new HttpsTransportSE(URL, 443, “”, 60000);
    transport.call(SOAP_ACTION, envelope);

    Appreciate your help.

    Thanks,
    Teresa

  27. 27
    Matt 

    Any luck finding an answer to Teresa’s question? I’m having the same problem. I’m fairly sure the 3rd parameter is the keystore with the certificate, but i’m not sure how to find that? Can you help?

    Thanks,
    Matt

  28. 28
    pyko 

    @allen & @Antoine
    Strangely enough just importing the root CA worked! I am able to login successfully everytime now (assuming I enter the correct credentials of course)

  29. @Martin
    I’m glad that you solved the problem. Thank you for commenting the solution here.

    @pyko
    Thank you very much for your testing.

    @Teresa & @Matt
    I’m sorry. I have no idea how to solve this one. Never used ksoap2. I can’t find any useful reference for the parameters in the HttpsTransportSE constructor. Maybe this entry helps a bit:http://stackoverflow.com/questions/2248147/andoird-ksoap2-https-problem/4438993#4438993

    Keep on going and please let me know if you found a solution. Thanks

반응형
AND
[code]
public class Test extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        StringBuilder content = new StringBuilder();
        
        try
        {
            String data = "userid=???&password=???";
            URL url = new URL("https://url~~");
            
            HttpURLConnection http = null;
            
            if (url.getProtocol().toLowerCase().equals("https")) {
                trustAllHosts();
                HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
                https.setHostnameVerifier(DO_NOT_VERIFY);
                http = https;
            } else {
                http = (HttpURLConnection) url.openConnection();
            }
            http.setDoOutput(true);
            OutputStreamWriter wr = new OutputStreamWriter(http.getOutputStream());
            wr.write(data);
            wr.flush();
            
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(http.getInputStream()));

            String line;

            while ((line = bufferedReader.readLine()) != null)
            {
              content.append(line + "\n");
            }
            Log.i("content", content.toString());
            wr.close();
            bufferedReader.close();
        }
        catch(Exception e)
        {
        }
    }
    
    private static void trustAllHosts() {
        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return new java.security.cert.X509Certificate[] {};
                }

                @Override
                public void checkClientTrusted(
                        java.security.cert.X509Certificate[] chain,
                        String authType)
                        throws java.security.cert.CertificateException {
                    // TODO Auto-generated method stub
                    
                }

                @Override
                public void checkServerTrusted(
                        java.security.cert.X509Certificate[] chain,
                        String authType)
                        throws java.security.cert.CertificateException {
                    // TODO Auto-generated method stub
                    
                }
        } };

        // Install the all-trusting trust manager
        try {
                SSLContext sc = SSLContext.getInstance("TLS");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                HttpsURLConnection
                                .setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (Exception e) {
                e.printStackTrace();
        }
    }
    
    final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };
}
[/code]

반응형
AND
http://tokudu.com/2010/how-to-implement-push-notifications-for-android/ 

안드로이드에서 Push notification을 구현하기 위한 방법으로 XMPP를 이용하는 방법과 MQTT를 이용하는 방법이 있다..
여기서는 MQTT를 이용하여 C2DM을 지원하지 않는 안드로이드 2.1이하 버전에서 PUSH notification을 지원하기 위한 방법에 대해 설명한다.

안드로이드 앱에서 Push notification을 지원하기 위한 방안은 3가지정도의 방안이 있다.
1. 폴링
  이게 진정 push일까?? 어쨌든 단말에서 주기적으로 서버에 가져갈 메세지가 있는지 확인하여 push event를 수신할 수 있다. 
  장점 : 구현이 쉽고 비용도 안든다.
  단정 : 실시간이 아니지 않은가... 이런 젝일~!, 이는 배터리소모까지 발생시킨다.. 끔찍하다.이에 대한 정보는 링크를 참조하자. https://labs.ericsson.com/apis/mobile-java-push/blog/save-device-battery-mobile-java-push
2. SMS
  안드로이드는 SMS message의 가로채기가 가능하다. 서버에서 특별한 SMS를 단말에 날리면 앱에서는 모든 SMS 메세지를 가로채서 서버에서 날린것인지 확인하고 Popup Message를 띄울 수 있을것이다.
  장점 : 구현이 쉽다. 완전한 실시간이 보장된다. 알려진 솔루션도 있다. Ericsson lab의 자료를 참조하라 https://labs.ericsson.com/apis/mobile-java-push/
  단점 : 비용이 발생한다.
3. 끊김없는 TCP/IP
  폰과 서버가 TCP/IP 연결을 유지한다. 그리고 주기적으로 keepalive메세지를 날린다. 서버는 이 연결을 통해 필요할경우 메세지를 보낸다.
  장점 : 완전한 실시간이 보장된다.
  단점 : 신뢰성을 보장하는 구현이 아주 까다롭다. 폰과 서버쪽 모두 구현하려면 이야기가 복잡해진다. 또 안드로이드는 low memory등의 상황에서 서비스가 종료될 수도 있다. 그러면 동작을 안할것이다. 또한 단말이 sleep에 들어가지 않아야 하므로 유저들은 배터리문제로 클레임을 걸수 있다.

1, 2의 방법은 중대한 단점이 있다. 3번째는 가능하기는 하다. 하지만 먼가 개운치는 않다.

구글링을 통해서 몇몇 개발자들의 TCP/IP방식의 몇가지 좋은 시도를 찾았다.
Josh guilfoyle은 AlarmManager에 기반하여  오랬동안 살아있는 connection을 어떻게 만들것인가에 대해 언급했다. 그는 백그라운드에서 동작하면서 그 연결을 만들어내는 멋진 샘플코드도 제공하였다. http://devtcg.blogspot.com/2009/01/push-services-implementing-persistent.html

Dave Rea는  Deacon project를 최근에 시작했다. Meteor server상에서 comet technology를 사용하여 안드로이드에서 push notification을 지원하는 3rd party library를 개발할 예정이다. 아주 초기 단계이다.  http://deacon.daverea.com/

Dale Lane는 IBM에서 개발한 MQTT protocol로 android에서 push notification을 지원하는것과 관련한 많은 자료를 만들었으며 아주 훌룡한 샘플코드도 제공한다. http://dalelane.co.uk/blog/?p=938

위의 훌룡한 시도들을 기반으로 예제를 만들었다. 이 는 Josh Guilfoyle의 TestKeepAlive project 와 Dale Lane의 MQTT를 이용한 것이다.

TestKeepAlive project의 문제점은 raw TCP connection을 만든다는 것이다. 이는 push를 관리하는 서버를 별도로 작성해야 한다는것을 의미한다. MQTT를 이용한 예제의 경우 서버작업을 위해 IBM의 MQTT broker를 이용한다. 

mqtt는 publish/subscribe messaging protocol로 가볍게 설계 되었다. 가볍게 설계 되었다는 것은 '저전력 소모'를 지원한다는 것이다. 이는 끊김없는 TCP/IP connection을 고려해야 하는 모바일환경에서 가장 이상적인 해결책이다. 다만 MQTT의 단점은 개인의 프라이버시 보장이 약하다는 것등 몇가지 단점이 있기는 하다.

KeepAliveService와 raw TCP/IP connection을 MQTT connection으로 변경하는 것이 아이디어의 핵심이다.

Architecture
예제에서는 서버에서 PHP를 사용하였다. 이는 Simple Asynchronous Messaging library(http://project-sam.awardspace.com/)를 사용하였다.



wmqtt.tar 는 IBM에서 제공하는 MQTT protocol의 간단한 drop-in implementation이다.  http://www-01.ibm.com/support/docview.wss?rs=171&uid=swg24006006에서 다운로드 가능하다. 

Really Small Message Broker(RSMB)는 간단한 MQTT broker로 마찬가지로 IBM에서 제공한다. http://www.alphaworks.ibm.com/tech/rsmb에서 다운가능하다. 1833포트가 디폴트로 동작한다. 위 아키텍쳐에서 서버로부터 메세지를 받아서 단말에 전송하는 역할을 한다. RSMB는 Mosquitto server(http://mosquitto.atchoo.org/)로 변경이 가능하다.
SAM은 MQTT와 다른 요소들을 모아놓은 PHP library이다. http://pecl.php.net/package/sam/download/0.2.0에서 다운가능하다.

send_mqtt.php는 POST를 통해 메세지를 받아서 SAM을 이용하여 broker에 메세지를 전달하는 역할을 한다.

Sample code and Demo

이 예제는 TextView하나와 두개의 Button이 있다. 폰에 설치 후 서비스를 시작한 후 http://tokudu.com/demo/android-push/  에 가서 deviceID를 입력하고 메세지를 입력하라. 그러고 난 후 "Send Push Message"를 누르면 폰에서 메세지를 받을 것이다. 


MQTT는 사실 안드로이드에서 Push를 지원하기 위한 최적의 방법은 아니다. 하지만 잘 동작한다. MQTT의 가장 취약한 점은 broker가 동작하는 IP와 PORT정보를 누군가 알아낸다면 모든 Push message들을 가로챌수 있다는 것이다. 따라서 그런 정보를 encrypt하는것은 좋은 대안이 될것이다. 대안으로 당신만의 broker를 작성하여 MQTT에 인증을 추가하는것이 있을 수 있다.

이 예제는 더 테스트되어야 한다. 안정성은 보장못한다. 연결이 끊어지거나 예외상황들에 대한 처리가 더 개선되어야 한다. 

반응형
AND
펌>http://seulkom.tistory.com/entry/Ubuntu-904-%EC%97%90%EC%84%9C-YAFFS2-Mount-%ED%95%98%EA%B8%B0

0. 커널 컴파일을 하기 위한 기본 셋팅


커널 컴파일을 위해선 다음의 package들이 필요

build-essential
kernel-package
libncurses5-dev                                    # ncurses 를 기반으로 하는 화면-menuconfig-에서 설정하기 위한 것
libgtk2.0-dev, libglib2.0-dev, libglade2-dev   # GTK 기반 화면-gconfig-에서 설정하려면 설치해야 할 것
libqt-mt-dev                                             # QT 기반 화면-xconfig-에서 설정하려면 필요한 것

[실행]
# apt-get install build-essential
# apt-get install kernel-package 
# apt-get install libncurses5-dev libgtk2.0-dev libglib2.0-dev libglade2-dev
# apt-get install libqt-mt-dev


Ubunut에는 linux-source가 default로 포함되어 있지 않으므로 linux-source도 설치
(시냅틱 패키지 관리에 가면 간단하게 설치 가능하다)

커널 소스를 다운 받으면, /usr/src/ 디렉토리 안에 저장됨
* 압축 풀고나서 /usr/src/linux-source-[kernel_version]에 들어가 menuconfig를 통해 kernel 옵션을 수정 ('3.' 에서 실행)

[실행]
# tar -xjvf linux-source-[kernel_version]


1. 서버에서 YAFFS2 다운로드





우리는 YAFFS2를 다운 받을 예정이므로
yaffs2/ 폴더에 들어 간 후 하단에 있는 Download GNU tarball 을 통해 tar 파일을 다운 받는다
다운받은 파일을 tmp 나 home 폴더 등 원하는 경로에 압축을 푼다

[실행]




2. /usr/src/linux-[version]/fs 경로에 YAFFS2 설치

YAFFS2 source를 linux-[version]에 포함시키기 위해 필요한 파일들을 /usr/src/linux-[version]에 저장한다.
이미 압축을 푼 폴더 내에 .sh 파일이 있으므로 이를 이용한다.
실행 하고 나면 자동으로 /usr/src/linux-[version]/fs/yaffs2 가 생겼음을 알 수 있다.


[실행]
# cd yaffs2
# ./patch-ker.sh                 // .sh 파일



3. make menuconfig 를 통해 config 파일 저장

(커널 메뉴 설정)
 make menuconfig 는 /usr/src/linux-[version]/ 디렉토리 안에서만 가능한 명령이다.

(각 디렉토리에 Makefile과 Kconfig가 존재한다. 이를 이용하여 menuconfig 에서의 메뉴형태를 변경할 수 있다)

/usr/src/linux-[version]/fs/yaffs2 에 존재하는 
Makefile과 Kconfig를 통해 원하는 방법으로 menuconfig를 수정 할 수 있다.



[실행]
# make menuconfig
File systems>Miscellaneous filesystem>YAFFS2 filesystem support

a. File systems를 선택한다

 
b. Miscellaneous filesystems 를 선택한다


 
c. YAFFS2 file system support 를 선택한다



4. 커널 설정 저장 후 커널 컴파일


exit 버튼을 누르고 save 창이 나오면 save를 한다.
설정값이 /usr/src/linux-[version]/.config 파일에 저장된다.


[실행]
# make clean                                  
# make bzImage install                     # vmlinuz 를 /boot 에 추가
# make modules modules_install       # /lib/modules 에 커널 추가



5. 새로 만든 커널 initrd를 통해 /boot/grub에 추가

vmilnuz              # 기존의 다른 linux에서 사용되는 bzImage 와 같다. bzImage를 rename
config                 # 커널 컴파일 시 사용된 config 파일
system.map      # fatal error가 발생한 경우 recover를 위해 필요한 파일
initrd.img           # root file system을 실제로 mount 하기 위한 파일

새로 만든 커널을 부팅 시 실행 하고 싶다면 grub에 initrd를 추가해야 한다.

[실행]
# cd /lib/modules
# update-initramfs -c -k [kernel_module_directory_name] 


실행하고 나면, /boot 에 initrd.img 파일이 생성된다.

Ubuntu가 9.10로 올라가면서 grubmf grub2로 업데이트 되었기 때문에
설정파일이 /boot/grub/menu.lst 에서 /boot/grub.cfg 로 변경
grub.cfg 는 readonly 파일이기 때문에 직접 수정하면 안된다.

[실행]
# update-grub
# grep "menuentry" /boot/grub/grub.cfg 


실행하면 생성된 initrd를 메뉴에 추가한 것을 확인 할 수 있다.
새로 만든 커널을 등록해서 부팅


6. Nandsim module 추가 및 YAFFS mount

/dev 디렉토리에 mtd와 mtdblock이 존재 하지 않으면 modprobe로 mtdblock을 추가
modprobe로 nandsim도 추가 후 yaffs 마운트

[실행]
# modprobe mtdblock
# modprobe nandsim
# insmod yaffs.ko
# mkdir [마운트 할 위치]
# mount -t yaffs2 /dev/mtdblock0 [마운트 할 위치]
# cat /proc/filesystems (확인)

* modprobe를 실행했을 경우 다음과 같은 에러가 발생하면
-----------------------------------------------------------------------------------------------------------------------------------
WARNING: all config files need .conf /etc/modprobe.d/vmware-tools it will be ignored in a future release
-----------------------------------------------------------------------------------------------------------------------------------

[실행]
# sudo mv /etc/modprobe.d/vmware-tools /etc/modprobe.d/vmware-tools.conf 






Reference : http://programmerjk.springnote.com/pages/2456582?print=1
                 http://wiki.kldp.org/wiki.php/KernelModuleProgrammingGuide
                 http://www.linux.co.kr/home2/board/bbs/board.php?bo_table=lecture&sca=1&sca2=32&sca3=&wr_id=1639


저작자 표시
반응형
AND
- 필요한 프로그램 다운로드
Eclipse IDE for Java Developers
Eclipse IDE for Java EE Developers
위 둘중 필요한 것 하나를 받으면 된다
본인의 환경에 맞는 SDK를 선택하여 받는다.
Java SE Development Kit (JDK6)

- 설치
1. JDK 설치
다운 받은 JDK를 설치하면 된다. 
2. Eclips 설치
받은 압축 파일을 원하는 폴더에 풀면 된다. 
3. Android SDK
받은 압축 파일을 원하는 폴더에 푼다.

- 설정
1. Eclips 3.5.1
설정을 시작하기 전에 환경변수를 등록해 주는 것이 좋다.
emulator와 툴킷의 환경을 일치시켜 주지 않으면 emulator을 시작할때 아래와 같은 메시지가 나타날 수 있어서 가능하면 등록해 주는 것 이 좋다.
emulator: ERROR: unknown virtual device name: 'nnnn'
emulator: could not find virtual device named 'nnnn'
환경변수 설정은 제어판=>시스템에서 고급탭을 선택하면 환경변수라는 버튼이 있는데 거기서 새로만들기 버튼을 눌러 다음과 같이 입력한다.
변수 이름 : ANDROID_SDK_HOME
변수 값: D:\android-sdk-windows <= android sdk 설치된 폴더

압축을 푼 Eclips 폴더의 eclips.exe 실행
eclipse에서 실행 했을경우 Failed to create the Java Virtual Machine 이란 에러가 뜨면
eclipse.ini에서
( 2. Find & Replace the line -vmargs with -vm D:\jdk1.6.0_23\bin\javaw.exe OR just remove the line -vmargs and save it . Now the problem is solved )
-- 추가 --
-vm
C:\Program Files\Java\jdk1.5\bin\javaw.exe
-- 추가 --

Android 개발툴 plugin 설치
Menu>>Help>>Install New Software
Add button 클릭

Name: 구별할 수 있는 이름 입력(ex, android plugin)
Location: https://dl-ssl.google.com/android/eclipse/
OK 클릭
잠시 기다라면 Pending 메시지가 사라지고 아래와 같이 Developer Tools 로 바뀐다. 이를 첵크하고 Next를 누른다.


잠시 기다리면 설치 상세 정보 창이 아래와 같이 나타난다.

Finish 버튼을 클릭하면 Android plugin 설치가 진행된다.  설치가 완료되면 Eclips를 재실행 한다.

2. Android SDK 설치
압축을 푼 폴더의 "SDK Setup.exe" 또는 "SDK Manager.exe"를 실행.
실행 도중 다음과 같은 화면이 나오면 왼쪽 메뉴의 Setting를 선택하여 
Force https:// ... source to be fetched using http:// 를 첵크한후 다시 Installed Package를 실행한다.

정상적으로 데이터를 가져오면 설치할 SDK 항목들이 나열되는데 필요한 것을 선택하여 설치하면 된다. 전부 선택해도 무방하다.

3. Eclips 설정
Menu>>Windows>>Preferances
좌측 메뉴중 Android 클릭 하면 우측에 SDK Location을 입력하는 항목이 나오면 Android SDK를 설치한 펄더를 지정하면 설치된 SDK가 보인다.

Menu>>Window>>Android SDK and AVD Manager
Virtual Device 생성 - emulator에서 사용할 가상 Device를 만든다.
실제 프로그램에서 사용할 장치들을 만들어 주지 않으면 프로그램을 할때 에러를 일으킨다. 



반응형
AND
WiFi가 말썽이다.
다른 장치들은 아무런 이상없이 연결이 잘되고 인터넷 접속도 잘되는데 모토로이만 안된다.
모토로이로부터 WiFi 접속이 완결되고 IP도 잘 받아오는데 AP로 ping이 안되는데 정확한 이유를 알 수 없다.
ping도 받아 보고 terminal 도 받아 실행해 봤지만 권한 문제로 해볼수 있는 것도 없다.
그래서 알아 본 것이 루팅인데 별로 어렵지는 않은 것 같다. 커널로 접근하는 것 까진 해 봤는데 WiFi 때문에 루팅해야 하나 몇일 고민좀 해보고...

반응형
AND
[펌]http://www.i-on-i.com/201
사용자 삽입 이미지
모토로라의 드로이드를 두달 넘게 사용하면서 유용하게 사용하는 여러가지 기능들을 소개하려 합니다. 앞으로 안드로이드용 스마트폰들이 국내에 출시될 예정이니 대부분의 기능들/팁들은 다 비슷할듯 싶네요.
특히 모토로라의 모토로이는 같은 회사 제품에 같은 안드로이드 2.0 버전을 사용하기 때문에 드로이드 대부분의 기능들이 똑같거나 비슷하리라 생각됩니다. 아시는 분들은 이미 알고 있는 기능들이나 팁이겠지만 안드로이드 스마트폰을 처음 사용하는 초보자님들에게는 유용한 정보가 되지 않을까 하네요. ^^

1. 문자에 상대방의 전화번호나 이메일 주소가 있을 경우에는 전화번호나 이메일 주소를 누르고 있으면 "Add to Contacts"이라는 메뉴가 나와 쉽게 주소록에 등록하실 수 있습니다.

2. 좌측 그림 하단의 버튼들 중 집 아이콘인 홈버튼을 길게 누르고 있으면 최근에 사용했던 6개의 프로그램들이 나타납니다. 노트북에서 멀티 작업을 하면서 화면 전환을 할때 Alt + Tap을 누르는 기능과 같은거죠. 앱과 앱 전환을 빠르게 하실 수 있습니다.

3. 드로이드를 컴퓨터와 USB로 연결시 반드시 Notification 메뉴를 누르셔서 "Mount"를 선택하셔야만 컴퓨터가 MicroSD 카드를 외부 저장 장치로 인식합니다. 무조건 USB 케이블 연결만 하시고 인식될때 까지 기다리시면 아무일도 안일어 납니다. ^^

4. 안드로이드폰은 자신이 가지고 있는 MP3 음악들을 바로 링톤으로 바꾸실 수 있습니다. 듣는 음악을 선택해서 누르고 있으면 링톤으로 설정할거냐는 메뉴가 뜨죠. 그리고 링톤으로 설정한다고 누르시면 자신이 좋아하는 음악을 링톤으로 바로 바꾸실 수 있습니다. 다만 이렇게 링톤을 설정할 경우 원하는 부분을 선택해서 설정할 수 없기 때문에 노래 처음 부분 30초(?)가 기본적으로 선택되어 집니다. 원하는 부분을 선택해서 링톤으로 설정하시길 원하시면 무료앱인 Ringdroid를 사용하시면 원하시는 부분을 쉽게 설정하셔서 사용하실 수 있습니다.

5. 드로이드에는 자동차용 거치대에 설치시 Car Mode로 자동 전환이 됩니다. 이렇게 바로 인식하는 이유가 자동차용 마운트에 설치된 자석때문인데요. 드로이드용 케이스를 구입할 시 똑딱이 자석이 들어간 녀석을 구입할 경우 Car Mode로 자동 인식을 해서 주머니 안에서 계속해서 켜져 있을 경우가 있습니다. 케이스 구입시에 똑딱이 자석이 없는걸 구입하시는게 좋겠네요. ^^

6. 드로이드는 각종 알람 소리들이 들어 있습니다. 메일이 새롭게 도착했다거나 음성 사서함 메세지가 도착했다거나 새로운 문자가 왔을경우등 여러가지 알람 소리들을 들려 주어 사용자에게 알려 주는데요. 드로이드에 저장된 음원들 외에 자신이 원하는 음원을 통해 알람 소리를 바꾸고 싶다면 컴퓨터와 연결해서 SD 카드 안에 "notifications"라는 폴더를 만들어 그 안에 자신이 원하는 음원 파일을 넣으시면 됩니다.

7. 드로이드에는 슬라이드 쿼티 키보드가 있는데요. 컴퓨터처럼 Shift+Alt+Del 키를 같이 누르면 리셋이 가능합니다. 물론 아이폰처럼 상단 전원 버튼을 오래 누르고 있으면 Power Down이라는 메뉴가 뜨죠. 그리고 그걸 누루신 후 드로이드를 끄고 난뒤에 다시 전원 버튼을 눌러 켜시면 됩니다. 때로는 전원 버튼도 먹통일 경우가 종종 있는데요. 이럴때는 배터리 커버를 열어 배터리를 뺐다가 다시 꽂은뒤 전원을 켜시면 됩니다.

8. 미국에서 드로이드를 사용하다 보면 데이터가 커버되지 않는 지역을 갈 경우가 있습니다. 이럴때는 Data Roaming 옵션을 On 하셔야 하는데 이 옵션을 On할 경우 과도한 요금이 부과 될 수 있는다는 메세지가 뜨죠. 하지만 미국내에서는 Data Roaming 옵션을 On해도 요금이 부과 되지 않습니다. 드로이드를 네비게이터처럼 사용해서 운전하고 갈 경우 Data Roaming 지역으로 들어가면 Data를 받지 못해 지도가 하얗게 나오는 경우가 있는데요. 이럴 경우에는 Data Roaming을 On 하신 후에 네비게이션 기능을 사용하시면 됩니다. 북미 지역 안에서는 Data Roaming 요금 부과는 없습니다. ^^

9.  YouTube를 3G 네크워크로 시청시에 아이폰과 마찬가지로 저화질로 보게 됩니다. 화질이 너무 좋지 않아 보기도 힘들죠. 하지만 드로이드는 아이폰과 다르게 고화질 옵션이 있습니다. 유투브 동영상을 3G로 시청시 메뉴 버튼을 누르시고 More를 누르시면 "Watch in high Quality"라는 옵션이 있습니다. 이 옵션을 선택하면 깨끗한 화질로 유투브를 시청하실 수 있습니다. (미국내는 데이터가 무제한이니 상관 없겠지만 국내에는 데이터 용량 제한이 있기 때문에 사용하면 데이터 용량을 많이 쓴다는것 염두해 두셔야 겠네요. ^^)

10. 가상 키보드를 사용할 경우 대문자를 계속해서 사용해야 하는 경우가 생기죠? 이럴 경우에는 왼쪽 Shift 키를 두번 누르시면 Shift 키에 초록색 불이 켜질 겁니다. 대문자로 lock이 되었다는 뜻이죠. 이럴 경우에는 Shift 키를 누르고 있지 않아도 계속해서 대문자를 사용하실 수 있습니다. 아이폰에는 없는 기능인듯 싶은데요. 유용합니다. ^^

11. 돋보기 모양의 검색 버튼을 누르고 있으면 바로 음성 검색으로 넘어갑니다. ^^

12. 요즘 스마트폰들은 스마트폰의 위치에 따라 자동적으로 가로 세로로 화면을 전환 시켜주는데요. 때로는 자동적으로 화면 전환 되는것이 불편할때가 있습니다. 아이폰에서는 탈옥을 하지 않고서는 불가능한 기능이지만 안드로이드에는 기본적인 기능으로 탑재 되어 있습니다. Settings --> Sound and Display에 가셔서 Orientation 옵션을 끄거냐 켜시면 됩니다. 세팅에 들어가기 귀찮을 경우에는 AutoRotate OnOff라는 앱을 다운로드 받아서 설치하시면 OnOff 스위치 위젯을 통하여 간단하게 세로 위치로만 고정 시킬 수 있습니다. (가로 위치 고정이 안되는 단점이 있네요. ^^)

13. WiFi이나 Bluetooth등을 쉽게 끄고 켜기 위해 3rd party 위젯등을 인스톨 하는 경우가 많은데요. 드로이드 자체에 그러한 기능을 가지 위젯이 있습니다. 홈 스크린을 길게 누르고 있으면 Add Widget이라는 메뉴가 뜨시면 Widget Power Control이라는 위젯을 선택하시면 됩니다.

14. 드로이드는 비밀번호보다 패턴을 이용하여 휴대폰을 잠그는 방법이 있죠. 얼마전에 글로 소개 한적이 있는데요. Menu --> Settings --> Location & Security 에 들어가시면 Change unlock pattern이란 메뉴가 있습니다. 이리로 들어 가셔서 자신만의 패턴을 만들어서 조금더 안전하게 드로이드를 가지고 다니세요. ^^

15. 드로이드에는 사진을 찍는 금색 버튼이 따로 있습니다. 이 버튼을 조금 오래 누르고 있으면 자동적으로 사진 기능으로 넘어갑니다. 그리고 이 버튼을 이용해 사진을 찍으면 되는거죠. ^^

16. 슬라이드 쿼티 키보드를 이용하여 단축키를 사용하실 수 있습니다. 검색 아이콘을 누르신 후에 단축키를 누르면 프로그램이 바로 실행이 되는거죠. ^^
search + e: email
search + y: youtube
search + b: browser
search + c: contacts
search + g: gmail
search + l: calendar
search + p: music
search + s: messaging
세팅에 가셔서 검색키를 바꾸실 수 있습니다. (Settings --> Application Settings --> Quick Launch)

17. 음성 검색을 이용하여 자신이 전화하고 싶은 사람의 이름을 말한뒤에 검색결과가 맞을 경우 "다이얼"이라고 외치면 자동적으로 전화를 걸어 줍니다. ^^

18. 인터넷을 할경우 웹브라우징 중에 back 버튼을 눌러 전 페이지로 가능 일이 많죠. 웹브라우저을 연 후에 초기 계속해서 서핑하다가 초기 페이지로 가려면 back 버튼을 수도 없이 눌러야 하는 불편함이 있었을 겁니다. 이럴때는 Back 버튼을 오래 누르고 있으면 웹브라우징이 처음 시작된 페이지로 바로 갑니다. ^^

19. 쿼티 키보드를 이용하여 번호를 쓸 경우에는 Alt키를 누르고 있어야 하는데요. 계속해서 번호를 넣어야 할 경우 꽤 불편합니다. 한손으로는 Alt 키를 누르고 있고 나머지 한손으로 왼쪽 1부터 오른쪽 0까지 왔다 갔다 해야 하니까요. 이렇게 계속해서 번호를 써야 할 경우에는 Alt키를 두번 누르시면 Alt 키가 고정이 되기 때문에 두손으로 번호를 넣을 수 있습니다. 고정을 해제 시키시려면 Alt 키를 다시 두번 누르시면 됩니다.

20. 안드로이드 2.0일 경우 바탕 화면을 3개 까지 밖에 사용 못하고, 2.1인 넥세서원과 같은 안드로이드 폰도 5개까지 밖에 사용할 수 없습니다. 앱들이 많아질수록 관리하기가 어렵죠. 이럴때 Apps Organizer라는 무료앱을 통하여 자신이 원하는 카테고리를 만들고 그 안에 찾기 쉽게 정렬하실 수 있습니다. 게임앱들은 게임 카테고리에 넣고 음악앱들은 Music 카테고리에 넣고 말이죠.

21. 내 전화기가 슬립 모드로 될 경우 WiFi 접속도 저절로 꺼지게 됩니다. 다시 드로이드를 켜면 그때 다시 WiFi를 잡으려는 모습을 볼 수 있죠. 이렇게 슬립 모드를 전환될때 마다 WiFi를 끄지 않으시려면 Settings --> Wireless & Networks --> WiFi Settings에 가셔서 Menu 버튼을 선택하시고 Advanced를 선택하시면 3가지 옵션이 나옵니다.
a. When screen turns off(기본설정입니다.)
b.Never when plugged in
c. Never
이 설정중 Never를 설정하시면 슬립 모드에서 다시 드로이드를 켜도 WiFi는 그대로 있습니다. ^^

그밖에 더 많은 기능들이 숨어 있을겁니다. 사용하다보면, 인터넷을 돌아다니다 보면 더 찾을 수 있겠죠. 혹시나 안드로이드 폰 유저분들이 윗 글을 보시고 자신이 찾은 숨은 기능들을 소개 시켜주면 더 좋겠네요. ^^
앞으로 안드로이드 폰들이 줄줄히 출시되면 더 유용한 정보들을 공유할 수 있게 되겠네요. ^^
반응형
AND

sudo apt-get install mysql-server mysql-client libmysqlclient15-dev
apt-get install apache2
apt-get install php5 php5-mysql libapache2-mod-php5
apt-get install php5-gd
apt-get install zlib1g
apt-get install zend


vi /etc/apache2/mods-available/php5.conf
==> 수정
  AddType application/x-httpd-php .php .phtml .php3 .html

/etc/init.d/mysql stop
/etc/init.d/apache2 stop
/etc/init.d/mysql start
/etc/init.d/apache2 start


http://kr.shoppingos.net
==> Download>쇼핑 OS G>소스다운로드

mkdir /var/www/gw
chmod 777 /var/www/gw

압축 해제

vi vi G_business.sql.txt
 default '한글' => default ''변경

=> 변경
INSERT INTO shoppingos_admin (no, id, name, email, pw, contents, authority, _def, _defav, os, connect_os, date) VALUES
(1, 'admin', 'Supervisor', 'dummypost@gmail.com', password('00000'), 'Supervisor', 5, 1, 'n,n,n,n,n,n,n,n,rw', 'groupos', 'all', now());

 
mysql -u root -p

source ./G_business.sql.txt
...error ...
한글을 default '' 변경

create database nucron ; // 'nucron' <= root@chjeong-desktop:/var/www/gw/_System_/Resource/mysql/class.mysql.php 수정한 데이터베이스

use nucron
source ./G_business.sql.txt
source ./zipcode.sql



 

반응형
AND
꼭 Ubuntu에만 해당하는 것은 아니다. mplayer가 설치되어 있으면 된다. mplayer에서 mms 파일을 다운로드 받을 수 있는 기능을 제공한다. 

먼저 mplayer를 설치한다.

$ sudo apt-get install mplayer mplayer-nogui

mplayer-nogui가 의존성 에러가 나면 제외해도 된다. 필요가 없는거 같은데..

다음 다음의 명령어로 실행한다. 

$ mplayer -dumpstream -dumpfile [filename] [URL]

filename: 저장될 파일이름을 입력한다.
URL: 소스 URL을 지정한다.
반응형
AND
첨부파일을 풀면
bootsect 
petousb_3.0.0.7
usb_prep8
세개의 폴더가 만들어 진다.

1. 부팅디스크 만들기

PeToUSB.exe 를 실행하여 다음과 같이 포맷한다.


2. 부트섹터 만들기
bootsect 폴더의 BootSect.exe를 cmd 창에서 실행한다.
bootsect /help를 해보면 다양한 옵션을 볼수 있는데 사용한 방법은 bootsect /nt52 F: 로 하였다.
/nt52는 비스타 이전 버전의 윈도우즈 설치에 사용하는 옵션이고 F:는 USB stick의 드라이브 이름이다.

3. 부트이미지 만들기
usb_prep8폴더의 usb_prep8.cmd 파일을 cmd 창에서 실행하면 이미지 파일이 복사된다.
1) 콘솔에 0-6번 명령을 입력 받게 되어 있는데 0번은 usb stick인지 hdd인지를 선택하는 것인데 토글된다. usb stick로 선택되게 한다.
2) 1번은 XP 설치 디스크를 선택한다. iso 파일인 경우 데몬이나 울트라ISO 등을 이용하여 드라이브로 마운트 한 후 사용하면 된다
3) 2번은 이미지를 만들기 위한 가상 드라이브 명인데 기본인 T:로 그냥 두어도 되고 사용하지 않는 드라이브명을 입력하면 된다.
4) 3번은 이미지 파일을 복사할 USB stick 드라이브 명을 입력하는 옵션이다.
5) 4를 선택하면 파일이 복사되기 시작하는데 특별한 경우를 제외하고는 yes를 선택하면 된다. 나의 경우에는 모두 yes를 선택하였다.

이상 위 절차데로 하여 설치 메모리를 만들어 설치하면 된다.

반응형
AND

ARCHIVE

CALENDAR

«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

RECENT TRACKBACK

RECENT COMMENT

RECENT ARTICLE

ARTICLE CATEGORY

분류 전체보기 (175)
가족일기 (3)
낙서장 (39)
밥벌이 (30)
추억 (6)
사회 (27)
혼자만의 방 (2)
생태 (4)
눈여겨 보는 곳 (1)
어머니 일기 (38)
윤선애 (1)
생활 단식 (11)
동거동락 자전거 (2)
반응형