当前位置: 编程技术>移动开发
本页文章导读:
▪AsyncTask展示sd卡所有图片 AsyncTask显示sd卡所有图片
java代码:package blog.android.sdcard2; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; .........
▪ Objective-C Unicode 转换成汉语 Objective-C Unicode 转换成中文
+ (NSString *)replaceUnicode:(NSString *)unicodeStr {
NSString *tempStr1 = [unicodeStr stringByReplacingOccurrencesOfString:@"\\u" withString:@"\\U"];
NSString *tempStr2 = [tempStr1 stringByReplacingOccurrencesO.........
▪ 要保险还是要用户体验?简谈智能手机终端签名验证机制 要安全还是要用户体验?简谈智能手机终端签名验证机制
大部分的智能手机系统安装和运行一个应用软件,都需要证书的签名认证。未经任何签名的程序是不能在智能手机上安装和运行的.........
[1]AsyncTask展示sd卡所有图片
来源: 互联网 发布时间: 2014-02-18
AsyncTask显示sd卡所有图片
java代码:
package blog.android.sdcard2;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.AdapterView.OnItemClickListener;
/**
* Loads images from SD card.
*
* @author Mihai Fonoage
*
*/
public class LoadImagesFromSDCardActivity extends Activity implements
OnItemClickListener {
/**
* Grid view holding the images.
*/
private GridView sdcardImages;
/**
* Image adapter for the grid view.
*/
private ImageAdapter imageAdapter;
/**
* Display used for getting the width of the screen.
*/
private Display display;
/**
* Creates the content view, sets up the grid, the adapter, and the click listener.
*
* @see android.app.Activity#onCreate(android.os.Bundle)
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Request progress bar
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.sdcard);
display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
setupViews();
setProgressBarIndeterminateVisibility(true);
loadImages();
}
/**
* Free up bitmap related resources.
*/
protected void onDestroy() {
super.onDestroy();
final GridView grid = sdcardImages;
final int count = grid.getChildCount();
ImageView v = null;
for (int i = 0; i < count; i++) {
v = (ImageView) grid.getChildAt(i);
((BitmapDrawable) v.getDrawable()).setCallback(null);
}
}
/**
* Setup the grid view.
*/
private void setupViews() {
sdcardImages = (GridView) findViewById(R.id.sdcard);
sdcardImages.setNumColumns(display.getWidth()/95);
sdcardImages.setClipToPadding(false);
sdcardImages.setOnItemClickListener(LoadImagesFromSDCardActivity.this);
imageAdapter = new ImageAdapter(getApplicationContext());
sdcardImages.setAdapter(imageAdapter);
}
/**
* Load images.
*/
private void loadImages() {
final Object data = getLastNonConfigurationInstance();
if (data == null) {
new LoadImagesFromSDCard().execute();
} else {
final LoadedImage[] photos = (LoadedImage[]) data;
if (photos.length == 0) {
new LoadImagesFromSDCard().execute();
}
for (LoadedImage photo : photos) {
addImage(photo);
}
}
}
/**
* Add image(s) to the grid view adapter.
*
* @param value Array of LoadedImages references
*/
private void addImage(LoadedImage... value) {
for (LoadedImage image : value) {
imageAdapter.addPhoto(image);
imageAdapter.notifyDataSetChanged();
}
}
/**
* Save bitmap images into a list and return that list.
*
* @see android.app.Activity#onRetainNonConfigurationInstance()
*/
@Override
public Object onRetainNonConfigurationInstance() {
final GridView grid = sdcardImages;
final int count = grid.getChildCount();
final LoadedImage[] list = new LoadedImage[count];
for (int i = 0; i < count; i++) {
final ImageView v = (ImageView) grid.getChildAt(i);
list[i] = new LoadedImage(((BitmapDrawable) v.getDrawable()).getBitmap());
}
return list;
}
/**
* Async task for loading the images from the SD card.
*
* @author Mihai Fonoage
*
*/
class LoadImagesFromSDCard extends AsyncTask<Object, LoadedImage, Object> {
/**
* Load images from SD Card in the background, and display each image on the screen.
*
* @see android.os.AsyncTask#doInBackground(Params[])
*/
@Override
protected Object doInBackground(Object... params) {
//setProgressBarIndeterminateVisibility(true);
Bitmap bitmap = null;
Bitmap newBitmap = null;
Uri uri = null;
// Set up an array of the Thumbnail Image ID column we want
String[] projection = {MediaStore.Images.Thumbnails._ID};
// Create the cursor pointing to the SDCard
Cursor cursor = managedQuery( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
projection, // Which columns to return
null, // Return all rows
null,
null);
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails._ID);
int size = cursor.getCount();
// If size is 0, there are no images on the SD Card.
if (size == 0) {
//No Images available, post some message to the user
}
int imageID = 0;
for (int i = 0; i < size; i++) {
cursor.moveToPosition(i);
imageID = cursor.getInt(columnIndex);
uri = Uri.withAppendedPath(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, "" + imageID);
try {
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
if (bitmap != null) {
newBitmap = Bitmap.createScaledBitmap(bitmap, 70, 70, true);
bitmap.recycle();
if (newBitmap != null) {
publishProgress(new LoadedImage(newBitmap));
}
}
} catch (IOException e) {
//Error fetching image, try to recover
}
}
cursor.close();
return null;
}
/**
* Add a new LoadedImage in the images grid.
*
* @param value The image.
*/
@Override
public void onProgressUpdate(LoadedImage... value) {
addImage(value);
}
/**
* Set the visibility of the progress bar to false.
*
* @see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
@Override
protected void onPostExecute(Object result) {
setProgressBarIndeterminateVisibility(false);
}
}
/**
* Adapter for our image files.
*
* @author Mihai Fonoage
*
*/
class ImageAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<LoadedImage> photos = new ArrayList<LoadedImage>();
public ImageAdapter(Context context) {
mContext = context;
}
public void addPhoto(LoadedImage photo) {
photos.add(photo);
}
public int getCount() {
return photos.size();
}
public Object getItem(int position) {
return photos.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
final ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mContext);
} else {
imageView = (ImageView) convertView;
}
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.setPadding(8, 8, 8,;
imageView.setImageBitmap(photos.get(position).getBitmap());
return imageView;
}
}
/**
* A LoadedImage contains the Bitmap loaded for the image.
*/
private static class LoadedImage {
Bitmap mBitmap;
LoadedImage(Bitmap bitmap) {
mBitmap = bitmap;
}
public Bitmap getBitmap() {
return mBitmap;
}
}
/**
* When an image is clicked, load that image as a puzzle.
*/
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
int columnIndex = 0;
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = managedQuery( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
projection,
null,
null,
null);
if (cursor != null) {
columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToPosition(position);
String imagePath = cursor.getString(columnIndex);
FileInputStream is = null;
BufferedInputStream bis = null;
try {
is = new FileInputStream(new File(imagePath));
bis = new BufferedInputStream(is);
Bitmap bitmap = BitmapFactory.decodeStream(bis);
Bitmap useThisBitmap = Bitmap.createScaledBitmap(bitmap, parent.getWidth(), parent.getHeight(), true);
bitmap.recycle();
//Display bitmap (useThisBitmap)
}
catch (Exception e) {
//Try to recover
}
finally {
try {
if (bis != null) {
bis.close();
}
if (is != null) {
is.close();
}
cursor.close();
projection = null;
} catch (Exception e) {
}
}
}
}
}
XML代码:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<GridView
android:id="@+id/sdcard"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center" />
</FrameLayout>
java代码:
package blog.android.sdcard2;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.AdapterView.OnItemClickListener;
/**
* Loads images from SD card.
*
* @author Mihai Fonoage
*
*/
public class LoadImagesFromSDCardActivity extends Activity implements
OnItemClickListener {
/**
* Grid view holding the images.
*/
private GridView sdcardImages;
/**
* Image adapter for the grid view.
*/
private ImageAdapter imageAdapter;
/**
* Display used for getting the width of the screen.
*/
private Display display;
/**
* Creates the content view, sets up the grid, the adapter, and the click listener.
*
* @see android.app.Activity#onCreate(android.os.Bundle)
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Request progress bar
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.sdcard);
display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
setupViews();
setProgressBarIndeterminateVisibility(true);
loadImages();
}
/**
* Free up bitmap related resources.
*/
protected void onDestroy() {
super.onDestroy();
final GridView grid = sdcardImages;
final int count = grid.getChildCount();
ImageView v = null;
for (int i = 0; i < count; i++) {
v = (ImageView) grid.getChildAt(i);
((BitmapDrawable) v.getDrawable()).setCallback(null);
}
}
/**
* Setup the grid view.
*/
private void setupViews() {
sdcardImages = (GridView) findViewById(R.id.sdcard);
sdcardImages.setNumColumns(display.getWidth()/95);
sdcardImages.setClipToPadding(false);
sdcardImages.setOnItemClickListener(LoadImagesFromSDCardActivity.this);
imageAdapter = new ImageAdapter(getApplicationContext());
sdcardImages.setAdapter(imageAdapter);
}
/**
* Load images.
*/
private void loadImages() {
final Object data = getLastNonConfigurationInstance();
if (data == null) {
new LoadImagesFromSDCard().execute();
} else {
final LoadedImage[] photos = (LoadedImage[]) data;
if (photos.length == 0) {
new LoadImagesFromSDCard().execute();
}
for (LoadedImage photo : photos) {
addImage(photo);
}
}
}
/**
* Add image(s) to the grid view adapter.
*
* @param value Array of LoadedImages references
*/
private void addImage(LoadedImage... value) {
for (LoadedImage image : value) {
imageAdapter.addPhoto(image);
imageAdapter.notifyDataSetChanged();
}
}
/**
* Save bitmap images into a list and return that list.
*
* @see android.app.Activity#onRetainNonConfigurationInstance()
*/
@Override
public Object onRetainNonConfigurationInstance() {
final GridView grid = sdcardImages;
final int count = grid.getChildCount();
final LoadedImage[] list = new LoadedImage[count];
for (int i = 0; i < count; i++) {
final ImageView v = (ImageView) grid.getChildAt(i);
list[i] = new LoadedImage(((BitmapDrawable) v.getDrawable()).getBitmap());
}
return list;
}
/**
* Async task for loading the images from the SD card.
*
* @author Mihai Fonoage
*
*/
class LoadImagesFromSDCard extends AsyncTask<Object, LoadedImage, Object> {
/**
* Load images from SD Card in the background, and display each image on the screen.
*
* @see android.os.AsyncTask#doInBackground(Params[])
*/
@Override
protected Object doInBackground(Object... params) {
//setProgressBarIndeterminateVisibility(true);
Bitmap bitmap = null;
Bitmap newBitmap = null;
Uri uri = null;
// Set up an array of the Thumbnail Image ID column we want
String[] projection = {MediaStore.Images.Thumbnails._ID};
// Create the cursor pointing to the SDCard
Cursor cursor = managedQuery( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
projection, // Which columns to return
null, // Return all rows
null,
null);
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails._ID);
int size = cursor.getCount();
// If size is 0, there are no images on the SD Card.
if (size == 0) {
//No Images available, post some message to the user
}
int imageID = 0;
for (int i = 0; i < size; i++) {
cursor.moveToPosition(i);
imageID = cursor.getInt(columnIndex);
uri = Uri.withAppendedPath(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, "" + imageID);
try {
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
if (bitmap != null) {
newBitmap = Bitmap.createScaledBitmap(bitmap, 70, 70, true);
bitmap.recycle();
if (newBitmap != null) {
publishProgress(new LoadedImage(newBitmap));
}
}
} catch (IOException e) {
//Error fetching image, try to recover
}
}
cursor.close();
return null;
}
/**
* Add a new LoadedImage in the images grid.
*
* @param value The image.
*/
@Override
public void onProgressUpdate(LoadedImage... value) {
addImage(value);
}
/**
* Set the visibility of the progress bar to false.
*
* @see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
@Override
protected void onPostExecute(Object result) {
setProgressBarIndeterminateVisibility(false);
}
}
/**
* Adapter for our image files.
*
* @author Mihai Fonoage
*
*/
class ImageAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<LoadedImage> photos = new ArrayList<LoadedImage>();
public ImageAdapter(Context context) {
mContext = context;
}
public void addPhoto(LoadedImage photo) {
photos.add(photo);
}
public int getCount() {
return photos.size();
}
public Object getItem(int position) {
return photos.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
final ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mContext);
} else {
imageView = (ImageView) convertView;
}
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.setPadding(8, 8, 8,;
imageView.setImageBitmap(photos.get(position).getBitmap());
return imageView;
}
}
/**
* A LoadedImage contains the Bitmap loaded for the image.
*/
private static class LoadedImage {
Bitmap mBitmap;
LoadedImage(Bitmap bitmap) {
mBitmap = bitmap;
}
public Bitmap getBitmap() {
return mBitmap;
}
}
/**
* When an image is clicked, load that image as a puzzle.
*/
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
int columnIndex = 0;
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = managedQuery( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
projection,
null,
null,
null);
if (cursor != null) {
columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToPosition(position);
String imagePath = cursor.getString(columnIndex);
FileInputStream is = null;
BufferedInputStream bis = null;
try {
is = new FileInputStream(new File(imagePath));
bis = new BufferedInputStream(is);
Bitmap bitmap = BitmapFactory.decodeStream(bis);
Bitmap useThisBitmap = Bitmap.createScaledBitmap(bitmap, parent.getWidth(), parent.getHeight(), true);
bitmap.recycle();
//Display bitmap (useThisBitmap)
}
catch (Exception e) {
//Try to recover
}
finally {
try {
if (bis != null) {
bis.close();
}
if (is != null) {
is.close();
}
cursor.close();
projection = null;
} catch (Exception e) {
}
}
}
}
}
XML代码:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<GridView
android:id="@+id/sdcard"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center" />
</FrameLayout>
[2] Objective-C Unicode 转换成汉语
来源: 互联网 发布时间: 2014-02-18
Objective-C Unicode 转换成中文
+ (NSString *)replaceUnicode:(NSString *)unicodeStr { NSString *tempStr1 = [unicodeStr stringByReplacingOccurrencesOfString:@"\\u" withString:@"\\U"]; NSString *tempStr2 = [tempStr1 stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; NSString *tempStr3 = [[@"\"" stringByAppendingString:tempStr2] stringByAppendingString:@"\""]; NSData *tempData = [tempStr3 dataUsingEncoding:NSUTF8StringEncoding]; NSString* returnStr = [NSPropertyListSerialization propertyListFromData:tempData mutabilityOption:NSPropertyListImmutable format:NULL errorDescription:NULL]; //NSLog(@"Output = %@", returnStr); return [returnStr stringByReplacingOccurrencesOfString:@"\\r\\n" withString:@"\n"]; }
可以把Unicode格式(\u7E8C)的字符串转换成中文。记录下以备后用。。。
[3] 要保险还是要用户体验?简谈智能手机终端签名验证机制
来源: 互联网 发布时间: 2014-02-18
要安全还是要用户体验?简谈智能手机终端签名验证机制
大部分的智能手机系统安装和运行一个应用软件,都需要证书的签名认证。未经任何签名的程序是不能在智能手机上安装和运行的。有的终端虽然能够安装和运行没有签名的应用程序,但是特殊api或敏感api却被限制使用,或者老是弹出气人的警告对话框。第三方应用程序的签名认证是智能手机操作系统或软件平台的安全策略。即要求各种运行的第三方应用程序和软件都需要数字签名。其核心部分包括开发者以及开发者完成的终端应用,通过对终端应用产生、发布、使用的完整生命周期建立认证和控制体系,形成点对点的安全控制,在为终端应用用户提供安全的终端应用之外,也为安全问题的责任追溯和版权的保护提供有效的证据支持。
软件开发者将生成私钥 (.pvk) 和证书请求文件 (CSR) 提交给证书颁发机构(CA) ,同时提交有关身份证明文件 ( 如:营业执照和第三方证明文件等 ) 给 CA 鉴证, CA 在验证身份后用自己的私钥给 CSR 文件签名后就生成代码签名证书,也就是公钥 (.spc 或 .cer) 文件给软件开发商,这样就完成了证书的申请和颁发过程。
软件开发者用代码签名工具 ( 如: signSIS) 给要签名的代码生成一个 Hash 表,再用其私钥加密 Hash 表产生认证摘要,接着就把认证摘要连同其公钥与软件代码一起打包生成签名后的新的软件代码。
最终用户安装或运行签名的应用软件时,手机智能操作系统会从签名代码中解读出其签名证书 ( 公钥 ) 和 Hash 表摘要,并与Windows 操作系统或 Symbian 移动操作系统中的受信任的根证书相比较查验公钥证书的有效性和合法性,验证签名证书正确后,就可以确认此代码确实是来自真实的软件开发商。
接着,再使用签名时使用的同样算法对软件代码生成一个 Hash 表,并使用公钥也同样生成一个 Hash 表认证摘要,比较从代码中解包出来的 Hash 表认证摘要与生成的 Hash 表认证摘要是否一致,如果一致,则表明此代码在传输过程中没有被篡改,从而可以确认代码的完整性。
由此,我们可以看出签名认证实际上分为两块:数字签名和验证签名
数字签名的基本过程是:签名工具对原始数据进行杂凑运算得到消息摘要,再使用签名私钥对消息摘要进行加密运算。
验证签名的基本过程则:智能手机操作系统或软件平台对收到的原始数据采用相同的杂凑运算得到消息摘要,将与被签署时候的消息摘要进行对比,以校验原始数据是否被篡改。
所以,通过数字签名技术可以实现对数据完整性、以及传送数据行为不可否认性的保护。
应用系统签名认证所需要的证书来源有三种模式:
第一种是自签名证书。这种方式以android为代表;android中的签名仅仅是让用户知道该应用的开发者,但没有验证开发者的身份
第二种OEM或移动运营商来颁发,这种方式以apple,rim为代表;这种方式安全是得到了保障,但对开发者来说是极其不爽
第三种是通过第三方商业性是权威的数字证书机构签名认证,比较著名的CA有:Verisign,Thawte。这种模式以windows mobile为代表
下面具体介绍一下各个手机操作系统或平台的数字签名运行机制或要点。
1、Android数字签名
Android数字包含以下几个要点:
(1)所有的应用程序都必须有数字证书,Android 系统不会安装一个没有数字证书的应用程序
(2)Android程序包使用的数字证书可以是自签名的,不需要一个权威的数字证书机构签名认证
(3)如果要正式发布一个Android ,必须使用一个合适的私钥生成的数字证书来给程序签名,而不能使用adt插件或者ant工具生成的调试证书来发布。
(4)数字证书都是有有效期的,Android只是在应用程序安装的时候才会检查证书的有效期。如果程序已经安装在系统中,即使证书过期也不会影响程序的正常功能。
(5)Android使用标准的java工具 Keytool and Jarsigner 来生成数字证书,并给应用程序包签名。
android数字签名的作用仅仅是
1)识别代码的作者
2)检测应用程序是否发生了改变
3)在应用程序之间建立信任,基于这一信任关系,应用程序可以安全地共享代码和数据。
2、windows mobile数字签名
windows mobile数字签名有以下3种策略:
(1)只准许运行签过名的程序;
(2)准许运行所有程序(包括未签名), 但是使用特权api的程序不能正常运行;
(3)包括使用了特权api的程序(不管有无签名)都可以运行.
一般用户选择的安全策略是第二种, 这样既在一定程度上保护了设备又能运行大部分的应用程序(一般网络上免费的那些应用程序都是没有签名的). 如果程序中使用了特权api, 如果不签名(而且要签特权的)的话那大部分用户都使用不了
3、Iphone数字签名
Iphone中的签名限制度是比较高的
所有iPhone 应用程序在iPhone OS设备上运行之前必须用合法的 signing identity 进行签名
iphone开发签名标识的获取:
1)使用Keychain Access utility里边的Certificate Assistant来创建一个签名许可请求Certificate Signing Request (CSR)
2)提交这个请求,得到使用iphone开发者计划的计划入口的正式许可证书文件。
3)安装证书文件
开发者提交应用程序给苹果审批和部署的时候,苹果会做如下工作:
1)苹果验证该程序代码是否来自有效的已注册的开发者。
2)苹果用自己的签名证书为你的已签名的应用程序签名。
这样,第三方应用程序才能够在iPhone ,iPod Touch上正常的运行。
当你安装了已签名的应用程序到你的iphone上去的时候,iphone OS 将要验证签名以确保该应用程序已签名并在签名以后未被篡改。如果签名无效或者你根本就没有签名,iphone OS 将不允许该应用程序运行。
签名之后,所有的应用文件、MIF中的权限,开发者也将不得再擅自改动了。
4、blackberry数字签名
出于安全和出口控制的原因,Research In Motion (RIM)必须跟踪一些敏感BlackBerry应用程序编程接口(API)的使用情况。敏感类别或方法在API参考文档中使用“锁定”图标或“Signed”字样表示。如果应用程序使用了这些受控类,应用程序.cod文件加载到BlackBerry智能手机之前,应用程序必须使用签名工具(由RIM提供)进行签名。
1)每次需要给cod文件签名的时候,机器需要连入Internet在线签名
2)签名工具将发送一个代码文件的SHA-1哈希到签名中心, 系统可以生成一个需要的签名.
3)加载一个签名.cod文件到BlackBerry设备时,VM将此.cod文件域API库连接,并且检验.cod文件是否需要签名.如果没有签名,VM停止连接,并且不再加载应用程序.
5、BREW数字签名
BREW中的签名限制度是极其高的,不支持普通CA颁发的证书的签名,更不要说随意的自签名了。 BREW中的签名,只认高通的根证书进行的签名。 也就是说,只有高通授权的应用,才能在手机中运行。
一般情况下,一个CP厂商的BREW应用想上线,必须经过天翼博路的详细测试,应用最终通过测试后,高通就会对整个应用包(包括应用的可执行文件mod,应用的模块信息文件mif,以及所有其他的应用文件)进行签名,然后返回CP厂商进行上线。
签名之后,所有的应用文件、MIF中的权限,开发者也将不得再擅自改动了。
6、j2me数字签名
MIDP 2.0 比 MIDP 1.0 增强了安全策略,把 API 分为普通 API 和敏感 API 。MIDlet 2.0 推出了可信任 MIDlet(trusted) 和不可信任 MIDlet(untrusted) 的概念,一个不可信任 MIDlet 只能访问有限的 API ,同时还需要用户手动确认并修改其安全策略;而可信任 MIDlet 则自动继承系统中的安全策略而获得访问许可。
j2me数字签名签名要点:
(1)基于 MIDlet 的安全策略,某些功能是必须签名才能使用的,而有些功能虽然不签名也可以使用,但必须要求用户在使用时确认和修改其安全策略,如:写用户数据缺省是不允许没有签名的 MIDlet 操作的;
(2)基于手机的系统安全和移动网络的安全考虑,某些手机制造商、移动运营商等可能拒绝没有签名的 MIDlet 在手机上安装和运行;
(3)大大改善用户体验,让用户使用方便,使得用户不会遭遇调用受保护 API 时的安全警告的烦恼;
(4)出于安全考虑,安装没有签名的 MIDlet 是会有安全警告的,而相反,安装已经签名的 MIDlet 则不会出现烦人的警告,手机会自动验证签名而顺利地安装成功;
(5)已经签名的 MIDlet 将使得用户能改善其低安全策略设置,提高手机的安全性;
(6)确保已经签名的 MIDlet 不会被非法篡改和非法盗用。
7、S60数字签名S60
第三版对在系统中安装运行的第三方软件有更为严格的规定。某些涉及手机软硬件安全于与个人信息安全等方面的操作被做了特别的限制(比如随手机开机自动启动就是被限制的功能之一)。应用程序要实现这些"被特别限制"了的功能就必须获得“签名”。未经任何
签名的程序不能安装运行。
签名又大致分2种:
1)Symbian 签名。
即 Symbian(塞班)手机操作系统官方签名。通过了 Symbian 安全认证的软件才会获得 Symbian 的签名。该类软件有最高的安全级别。在手机上能正常安装/运行/且能实现软件提供的所有功能.
2)开发者签名。
软件开发者在发布软件的时候就对软件进行了签名。这类软件可以在手机上安装运行(可能会遇到安全性警告,可跳过)。但不能实现那“被特别限制”了的功能。如果某软件根本不涉及这类功能,那么软件作者也完全可能自己签名就行了。还有一种可能就是软件虽然有某部分功能属于“被特别限制”的范围
本文欢迎转载,但请注明作者与出处
大部分的智能手机系统安装和运行一个应用软件,都需要证书的签名认证。未经任何签名的程序是不能在智能手机上安装和运行的。有的终端虽然能够安装和运行没有签名的应用程序,但是特殊api或敏感api却被限制使用,或者老是弹出气人的警告对话框。第三方应用程序的签名认证是智能手机操作系统或软件平台的安全策略。即要求各种运行的第三方应用程序和软件都需要数字签名。其核心部分包括开发者以及开发者完成的终端应用,通过对终端应用产生、发布、使用的完整生命周期建立认证和控制体系,形成点对点的安全控制,在为终端应用用户提供安全的终端应用之外,也为安全问题的责任追溯和版权的保护提供有效的证据支持。
软件开发者将生成私钥 (.pvk) 和证书请求文件 (CSR) 提交给证书颁发机构(CA) ,同时提交有关身份证明文件 ( 如:营业执照和第三方证明文件等 ) 给 CA 鉴证, CA 在验证身份后用自己的私钥给 CSR 文件签名后就生成代码签名证书,也就是公钥 (.spc 或 .cer) 文件给软件开发商,这样就完成了证书的申请和颁发过程。
软件开发者用代码签名工具 ( 如: signSIS) 给要签名的代码生成一个 Hash 表,再用其私钥加密 Hash 表产生认证摘要,接着就把认证摘要连同其公钥与软件代码一起打包生成签名后的新的软件代码。
最终用户安装或运行签名的应用软件时,手机智能操作系统会从签名代码中解读出其签名证书 ( 公钥 ) 和 Hash 表摘要,并与Windows 操作系统或 Symbian 移动操作系统中的受信任的根证书相比较查验公钥证书的有效性和合法性,验证签名证书正确后,就可以确认此代码确实是来自真实的软件开发商。
接着,再使用签名时使用的同样算法对软件代码生成一个 Hash 表,并使用公钥也同样生成一个 Hash 表认证摘要,比较从代码中解包出来的 Hash 表认证摘要与生成的 Hash 表认证摘要是否一致,如果一致,则表明此代码在传输过程中没有被篡改,从而可以确认代码的完整性。
由此,我们可以看出签名认证实际上分为两块:数字签名和验证签名
数字签名的基本过程是:签名工具对原始数据进行杂凑运算得到消息摘要,再使用签名私钥对消息摘要进行加密运算。
验证签名的基本过程则:智能手机操作系统或软件平台对收到的原始数据采用相同的杂凑运算得到消息摘要,将与被签署时候的消息摘要进行对比,以校验原始数据是否被篡改。
所以,通过数字签名技术可以实现对数据完整性、以及传送数据行为不可否认性的保护。
应用系统签名认证所需要的证书来源有三种模式:
第一种是自签名证书。这种方式以android为代表;android中的签名仅仅是让用户知道该应用的开发者,但没有验证开发者的身份
第二种OEM或移动运营商来颁发,这种方式以apple,rim为代表;这种方式安全是得到了保障,但对开发者来说是极其不爽
第三种是通过第三方商业性是权威的数字证书机构签名认证,比较著名的CA有:Verisign,Thawte。这种模式以windows mobile为代表
下面具体介绍一下各个手机操作系统或平台的数字签名运行机制或要点。
1、Android数字签名
Android数字包含以下几个要点:
(1)所有的应用程序都必须有数字证书,Android 系统不会安装一个没有数字证书的应用程序
(2)Android程序包使用的数字证书可以是自签名的,不需要一个权威的数字证书机构签名认证
(3)如果要正式发布一个Android ,必须使用一个合适的私钥生成的数字证书来给程序签名,而不能使用adt插件或者ant工具生成的调试证书来发布。
(4)数字证书都是有有效期的,Android只是在应用程序安装的时候才会检查证书的有效期。如果程序已经安装在系统中,即使证书过期也不会影响程序的正常功能。
(5)Android使用标准的java工具 Keytool and Jarsigner 来生成数字证书,并给应用程序包签名。
android数字签名的作用仅仅是
1)识别代码的作者
2)检测应用程序是否发生了改变
3)在应用程序之间建立信任,基于这一信任关系,应用程序可以安全地共享代码和数据。
2、windows mobile数字签名
windows mobile数字签名有以下3种策略:
(1)只准许运行签过名的程序;
(2)准许运行所有程序(包括未签名), 但是使用特权api的程序不能正常运行;
(3)包括使用了特权api的程序(不管有无签名)都可以运行.
一般用户选择的安全策略是第二种, 这样既在一定程度上保护了设备又能运行大部分的应用程序(一般网络上免费的那些应用程序都是没有签名的). 如果程序中使用了特权api, 如果不签名(而且要签特权的)的话那大部分用户都使用不了
3、Iphone数字签名
Iphone中的签名限制度是比较高的
所有iPhone 应用程序在iPhone OS设备上运行之前必须用合法的 signing identity 进行签名
iphone开发签名标识的获取:
1)使用Keychain Access utility里边的Certificate Assistant来创建一个签名许可请求Certificate Signing Request (CSR)
2)提交这个请求,得到使用iphone开发者计划的计划入口的正式许可证书文件。
3)安装证书文件
开发者提交应用程序给苹果审批和部署的时候,苹果会做如下工作:
1)苹果验证该程序代码是否来自有效的已注册的开发者。
2)苹果用自己的签名证书为你的已签名的应用程序签名。
这样,第三方应用程序才能够在iPhone ,iPod Touch上正常的运行。
当你安装了已签名的应用程序到你的iphone上去的时候,iphone OS 将要验证签名以确保该应用程序已签名并在签名以后未被篡改。如果签名无效或者你根本就没有签名,iphone OS 将不允许该应用程序运行。
签名之后,所有的应用文件、MIF中的权限,开发者也将不得再擅自改动了。
4、blackberry数字签名
出于安全和出口控制的原因,Research In Motion (RIM)必须跟踪一些敏感BlackBerry应用程序编程接口(API)的使用情况。敏感类别或方法在API参考文档中使用“锁定”图标或“Signed”字样表示。如果应用程序使用了这些受控类,应用程序.cod文件加载到BlackBerry智能手机之前,应用程序必须使用签名工具(由RIM提供)进行签名。
1)每次需要给cod文件签名的时候,机器需要连入Internet在线签名
2)签名工具将发送一个代码文件的SHA-1哈希到签名中心, 系统可以生成一个需要的签名.
3)加载一个签名.cod文件到BlackBerry设备时,VM将此.cod文件域API库连接,并且检验.cod文件是否需要签名.如果没有签名,VM停止连接,并且不再加载应用程序.
5、BREW数字签名
BREW中的签名限制度是极其高的,不支持普通CA颁发的证书的签名,更不要说随意的自签名了。 BREW中的签名,只认高通的根证书进行的签名。 也就是说,只有高通授权的应用,才能在手机中运行。
一般情况下,一个CP厂商的BREW应用想上线,必须经过天翼博路的详细测试,应用最终通过测试后,高通就会对整个应用包(包括应用的可执行文件mod,应用的模块信息文件mif,以及所有其他的应用文件)进行签名,然后返回CP厂商进行上线。
签名之后,所有的应用文件、MIF中的权限,开发者也将不得再擅自改动了。
6、j2me数字签名
MIDP 2.0 比 MIDP 1.0 增强了安全策略,把 API 分为普通 API 和敏感 API 。MIDlet 2.0 推出了可信任 MIDlet(trusted) 和不可信任 MIDlet(untrusted) 的概念,一个不可信任 MIDlet 只能访问有限的 API ,同时还需要用户手动确认并修改其安全策略;而可信任 MIDlet 则自动继承系统中的安全策略而获得访问许可。
j2me数字签名签名要点:
(1)基于 MIDlet 的安全策略,某些功能是必须签名才能使用的,而有些功能虽然不签名也可以使用,但必须要求用户在使用时确认和修改其安全策略,如:写用户数据缺省是不允许没有签名的 MIDlet 操作的;
(2)基于手机的系统安全和移动网络的安全考虑,某些手机制造商、移动运营商等可能拒绝没有签名的 MIDlet 在手机上安装和运行;
(3)大大改善用户体验,让用户使用方便,使得用户不会遭遇调用受保护 API 时的安全警告的烦恼;
(4)出于安全考虑,安装没有签名的 MIDlet 是会有安全警告的,而相反,安装已经签名的 MIDlet 则不会出现烦人的警告,手机会自动验证签名而顺利地安装成功;
(5)已经签名的 MIDlet 将使得用户能改善其低安全策略设置,提高手机的安全性;
(6)确保已经签名的 MIDlet 不会被非法篡改和非法盗用。
7、S60数字签名S60
第三版对在系统中安装运行的第三方软件有更为严格的规定。某些涉及手机软硬件安全于与个人信息安全等方面的操作被做了特别的限制(比如随手机开机自动启动就是被限制的功能之一)。应用程序要实现这些"被特别限制"了的功能就必须获得“签名”。未经任何
签名的程序不能安装运行。
签名又大致分2种:
1)Symbian 签名。
即 Symbian(塞班)手机操作系统官方签名。通过了 Symbian 安全认证的软件才会获得 Symbian 的签名。该类软件有最高的安全级别。在手机上能正常安装/运行/且能实现软件提供的所有功能.
2)开发者签名。
软件开发者在发布软件的时候就对软件进行了签名。这类软件可以在手机上安装运行(可能会遇到安全性警告,可跳过)。但不能实现那“被特别限制”了的功能。如果某软件根本不涉及这类功能,那么软件作者也完全可能自己签名就行了。还有一种可能就是软件虽然有某部分功能属于“被特别限制”的范围
本文欢迎转载,但请注明作者与出处
最新技术文章: